hdu-1712 ACboy needs your help---分组背包

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=1712

题目大意:

ACboy要开始选课了,上一门课能够获得的收益和他上这门课的时间是有关的,然后给你若干门课,让你帮他进行选课,
每一门课自然是只能选择一个课程时长,问你如何选择,才能使ACboy获得的受益最大。
思路:
分组背包,每门课只能选择一种学习时长

这里的组就是每门课程,价值v是总的学习时长,每门课程的所有的i就是该门课程所学习的时间

设dp[i][j]表示前i门课程花费时间j取得的最大收益

那么dp[i][j] = max(dp[i -1][j],dp[i - 1][j - t] +a[i][t])t表示第i门课程花费j天的时间

下面用的是二维数组,也可以用滚动数组,不过枚举j的时候需要逆序,道理和01背包是一样的

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 using namespace std;
 5 const int INF = 0x3f3f3f3f;
 6 const int maxn = 1e2 + 10;
 7 int T, n, m, cases;
 8 int dp[maxn][maxn];
 9 //dp[i][j]表示前i门课花费j天取得的最大收益
10 //dp[i][j] = max(dp[i-1][j], dp[i-1][j-t] + a[i][t])t为第i门课花费的时间
11 int a[maxn][maxn];
12 int main()
13 {
14     while(cin >> n >> m && (n + m))
15     {
16         memset(dp, 0, sizeof(dp));
17         memset(a, 0, sizeof(a));
18         for(int i = 1; i <= n; i++)
19             for(int j = 1; j <= m; j++)
20             cin >> a[i][j];
21         for(int i = 1; i <= n; i++)//枚举课程
22         {
23             for(int j = 0; j <= m; j++)//枚举已经花费的天数
24             {
25                 for(int t = 0; t <= j; t++)//枚举第i门课需要花费的天数
26                 {
27                     if(j >= t)dp[i][j] = max(dp[i][j], dp[i - 1][j - t] + a[i][t]);
28                 }
29             }
30         }
31         int ans = 0;
32         for(int i = 0; i <= m; i++)ans = max(ans, dp[n][i]);
33         cout<<ans<<endl;
34     }
35     return 0;
36 }

 

 

posted @ 2018-04-14 16:24  _努力努力再努力x  阅读(157)  评论(0编辑  收藏  举报