HDU 2602Bone Collector 01背包问题

题意:给出一个t代表有t组数据,然后给出n,n代表有n种石头,v代表旅行者的背包容量,然后给出n种石头的价值和容量大小,求能带走的最大价值

思路:01背包问题,每种石头只有拿与不拿两种状态、(其实我是为理解dp而来的)

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<iostream>
 5 const int qq=1000+10;    //开始数值写小了 只写了100+10 
 6 int value[qq];
 7 int weight[qq];
 8 int dp[qq][qq];
 9 void kill(int n,int v)
10 {    
11     for(int i=0;i<=n;++i)
12         dp[0][i]=dp[i][0]=0;
13     for(int j,i=1;i<=n;++i)
14         for(j=0;j<=v;++j)
15             if(j<weight[i])
16                 dp[i][j]=dp[i-1][j];
17             else if(dp[i-1][j-weight[i]]+value[i]>dp[i-1][j])
18                 dp[i][j]=dp[i-1][j-weight[i]]+value[i];
19             else
20                 dp[i][j]=dp[i-1][j];
21 }
22 int main()
23 {
24     int t,n,v;
25     scanf("%d",&t);
26     while(t--){
27         scanf("%d%d",&n,&v);
28         for(int i=1;i<=n;++i)
29             scanf("%d",&value[i]);
30         for(int j=1;j<=n;++j)
31             scanf("%d",&weight[j]);
32             kill(n,v);
33             printf("%d\n",dp[n][v]);
34     }
35 }

 一维数组也能过、只是第二层必须反序来、顺序的话同一件物品可能会被取多次

 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<cmath>
 5 #include<cstring>
 6 using namespace std; 
 7 const int qq=1050;
 8 int w[qq],v[qq];
 9 int dp[qq];
10 int main()
11 {
12     int t;
13     scanf("%d",&t);
14     while(t--){
15         int n,m;
16         memset(dp,0,sizeof(dp));
17         scanf("%d%d",&n,&m);
18         for(int i=1;i<=n;++i)
19             scanf("%d",&v[i]);
20         for(int i=1;i<=n;++i)
21             scanf("%d",&w[i]);
22         for(int i=1;i<=n;++i)
23             for(int j=m;j>=v[i];--j)    //一定记得是逆序、可以自己模拟一遍
24                 dp[j]=max(dp[j],dp[j-w[i]]+v[i]);;    
25         printf("%d\n",dp[m]);
26     }
27     return 0;
28 }

 

贴一份WA的代码

 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<cmath>
 5 #include<cstring>
 6 using namespace std; 
 7 const int qq=1050;
 8 int w[qq],v[qq];
 9 int dp[qq][qq];
10 int main()
11 {
12     int t;
13     scanf("%d",&t);
14     while(t--){
15         int n,m;
16         memset(dp,0,sizeof(dp));
17         scanf("%d%d",&n,&m);
18         for(int i=1;i<=n;++i)
19             scanf("%d",&v[i]);
20         for(int i=1;i<=n;++i)
21             scanf("%d",&w[i]);
22         for(int i=1;i<=n;++i)
23             for(int j=w[i];j<=m;++j)        //我开始还在想为什么这样不对 
24                 dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);                
25         printf("%d\n",dp[n][m]);
26     }
27     return 0;
28 } 
29 //先出一组数据吧、 
30 /*     1
31     5 0
32     2 4 1 5 1
33     0 0 1 0 0
34     这样的话在dp[3]的话是根本不会进入到第二层循环的、
35     也就是说dp[3][0]的值为0
36 */ 

 

posted @ 2016-03-01 16:44  我不萌、我要高冷  阅读(180)  评论(0编辑  收藏  举报