hdu 3496 Watch The Movie(二维背包)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3496

题意:有n部电影,给出他们的用时和价值,现在一定要看m部(不能多不能少),花的时间要少于等于l,问最大价值

题解:二维01背包问题,由于一定要看m部,要注意初值问题 

 

我的写法:

 1 #include <cstdio>
 2 #include <cstring>
 3 #define N 105
 4 #define L 1005
 5 
 6 int dp[N][N][L], time[N], value[N];
 7 int main()
 8 {
 9     int n, m, l, t;
10     scanf("%d",&t);
11     while(t--)
12     {
13         scanf("%d%d%d",&n, &m, &l);
14         for(int i=1; i<=n; i++)
15             scanf("%d%d",&time[i],&value[i]);
16         memset(dp, -1sizeof(dp));
17         //for(int i=0; i<=m; i++)
18         dp[0][0][0] = 0;
19         for(int i=1; i<=n; i++)
20         {
21             for(int j=0; j<=m; j++)
22             {
23                 for(int k=0; k<=l; k++)
24                 {
25                     if(dp[i][j][k] < dp[i-1][j][k]) dp[i][j][k] = dp[i-1][j][k];
26                     if(dp[i-1][j][k]==-1 || k+time[i]>l || j+1>m) continue;
27                     if(dp[i-1][j][k]+value[i]>dp[i][j+1][k+time[i]])
28                         dp[i][j+1][k+time[i]] = dp[i-1][j][k]+value[i];
29                 }
30             }
31         }
32 
33         int ans = 0;
34         for(int i=0; i<=l; i++)
35         {
36             if(ans<dp[n][m][i])
37                 ans = dp[n][m][i];
38         }
39         printf("%d\n",ans);
40     }
41     return 0;
42 }
View Code 

 用现在枚举到的状态去更新前面的状态。

dp[i][j+1][k+time[i]] = max(dp[i-1][j][k]+value[i], dp[i][j+1][k+time[i]])

 

this:

 1 #include<stdio.h>
 2 #include<string.h>
 3 #define INF 0xffffff
 4 int dp[105][1005],time[105],val[105];
 5 int MAX(int a,int b)
 6 {
 7     if(a>b) return a;
 8     return b;
 9 }
10 int main()
11 {
12     int t,i,j,k,n,m,l;
13 
14     scanf("%d",&t);
15     while(t--)
16     {
17         scanf("%d%d%d",&n,&m,&l);
18         for(i=0;i<n;i++) scanf("%d%d",time+i,val+i);
19         for(i=0;i<=l;i++) dp[0][i]=0;
20         for(i=1;i<=m;i++)
21             for(j=0;j<=l;j++)
22             dp[i][j]=-INF;
23 
24         for(i=0;i<n;i++)
25         {
26             for(j=m;j>0;j--)
27             {
28                 for(k=l;k>=time[i];k--)
29                 {
30                     if(dp[j-1][k]==-INF) continue;
31                     dp[j][k]=MAX(dp[j][k],dp[j-1][k-time[i]]+val[i]);
32                 }
33             }
34         }
35         if(dp[m][l]>0) printf("%d\n",dp[m][l]);
36         else printf("0\n");
37     }
38 
39     return 0;
40 }
View Code 

用前面的状态更新现枚举到在的状态

数组值初始化为无限大,可使恰好背包容量为恰好装满。

  1.  if(dp[j-1][k]==-INF) continue;  
  2.   dp[j][k]=MAX(dp[j][k],dp[j-1][k-time[i]]+val[i]);  

 

posted @ 2013-12-11 16:07  byluoluo  阅读(213)  评论(0编辑  收藏  举报