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神犇给讲的,好吧,我不会写……

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

原文地址:https://www.cnblogs.com/liuxueyang/p/3260211.html