链接:http://acm.hdu.edu.cn/showproblem.php?pid=1712
题意:acboy有n个课程,m天,在i课程花费j天的收益为a[i][j]。求最大收益。
思路:显然第i种课程收益a[i][1]~a[i][m]最多只能选一种。
b[i]表示i天前j-1种课程可获最大收益,dp[i]表示i天前j种课程可获最大收益。
则枚举每个a[i][k],dp[j+k] = max(dp[j+k], b[j]+a[i][k]) (0<=j<=m, 0<=j+k<=m)

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