• zoj3623 Battle Ships ——完全背包?简单DP!|| 泛化背包


    link:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3623

    看起来像完全背包,但是物品价值是变化的,所以很多人搞的很复杂。

    晚上的代码要么很复杂,有一个代码虽然很简洁在zoj可以过,但是是错误的。求教lyl神犇,果然思想很深刻,抓住乐问题的本质,想法比网上搜到的所有博客里面的做法都简洁。

    事实上,就是简单的DP,抓住一个技巧:让时间倒流,也就是说,把时间反过来考虑,先在将来把船造好,然后在过去用船攻击,哈哈,太巧秒了,说起来很别扭,很有意思,dp[j+time[i]]=max(dp[j]+j*time[i]);dp[j]表示在j这个时间,所造成的最大伤害。这样就可以枚举时间,在每个特定的时间内,枚举船的种类,找到最大值。最终在dp[]数组里面找到符合条件的并且时间最少的解。

    只能说,ORZ……

    后来好不容易想明白了。茶具从哪里来……

     1 /*
     2 ID: zypz4571
     3 LANG: C++
     4 TASK: battle.cpp
     5  */
     6 
     7 #include <iostream>
     8 #include <cstdio>
     9 #include <cstdlib>
    10 #include <cstring>
    11 #include <cmath>
    12 #include <cctype>
    13 #include <algorithm>
    14 #include <queue>
    15 #include <deque>
    16 #include <queue>
    17 #include <list>
    18 #include <map>
    19 #include <set>
    20 #include <vector>
    21 #include <utility>
    22 #include <functional>
    23 #include <fstream>
    24 #include <iomanip>
    25 #include <sstream>
    26 #include <numeric>
    27 #include <cassert>
    28 #include <ctime>
    29 #include <iterator>
    30 const int INF = 0x3f3f3f3f;
    31 const int dir[8][2] = {{-1,0},{1,0},{0,-1},{0,1},{-1,-1},{-1,1},{1,-1},{1,1}};
    32 using namespace std;
    33 int Time[33],dam[33], f[444];
    34 int main ( int argc, char *argv[] )
    35 {
    36 #ifndef ONLINE_JUDGE
    37 freopen("in.txt", "r", stdin);
    38 #endif
    39     ios::sync_with_stdio(false);
    40     int n,l;
    41     while (~scanf("%d%d",&n,&l)){
    42         for (int i=1;i<=n;++i) scanf("%d%d",Time+i,dam+i);
    43         memset(f,0,sizeof(f)); f[0]=0;
    44         for (int j=0;j<=355;++j) {
    45             for (int i=1;i<=n;++i) {
    46                 f[j+Time[i]]=max(f[j+Time[i]],f[j]+j*dam[i]);
    47             }
    48         }
    49         int ans=INF;
    50         for(int i=0;i<=355;++i) {
    51             if(f[i]>=l&&ans>i) ans=i;
    52         }
    53         printf("%d
    ",ans);
    54     }
    55         return EXIT_SUCCESS;
    56 }                /* ----------  end of function main  ---------- */

    学算法重在理解,思考,而不是套模板什么的。理解了就不用记忆了。

    比如这道题目,一看,就很想完全背包,然后就搞的很复杂的样子……

    其实,这道题目还有一个比较聪明的解法,因为时间最多只有300+,所以我们可以枚举时间,二分答案,对每个时间判断是否合法就OK,判断的时候,按照时间正序排就行,lyl神犇给讲的,好吧,我不会写……

    做完这道题目觉得动态规划很有意思。

  • 相关阅读:
    IPAD3终于发布了!苹果在5年内还是很难被超越!
    今天更新了ubuntu11.10!
    折腾两日系统重装,对比ubuntu11.04 和windows 7旗舰版!(不定时更新添加新的体验)
    DELL XPS M1530安装MAC OS X Lion 10.7.3经验分享!
    ubuntu 11.04 指纹识别的安装!
    Dlink DIR615L 和水星(mercury) MW300R桥接方法!
    POJ 3522 Slim Span(kruskal 变型)
    POJ 3621 Sightseeing Cows(SPFA + 构造负环)
    POJ 2553 The Bottom of a Graph(Tarjan)
    POJ 2728 Desert King(最优比率生成树)
  • 原文地址:https://www.cnblogs.com/liuxueyang/p/3260211.html
Copyright © 2020-2023  润新知