不知道这个称呼对不对-,反正是分组背包中的01那种类型的吧。见学长在做尝试了一下。
AC后去看讨论版发现还能用一维滚动数组去搞。然后第一次尝试一下竟然没对,果然是弱渣。然后发现毕竟是01类的分组背包,如果才有滚动数组的话是不是应该要按照01背包的滚动数组去搞,发现竟然对了- -。
状态转移方程:dp[i][j]=max(dp[i][j],dp[i-1][j-k]+a[i][k]);
滚动数组:dp[j]=max(dp[j],dp[j-k]+a[i][k]); j要逆序枚举。
二维数组:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int dp[105][105],a[105][105];
int max(int x,int y)
{
if(x>y)
return x;
return y;
}
int main()
{
int n,m,i,j,k;
while(scanf("%d %d",&n,&m),n+m)
{
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
scanf("%d",&a[i][j]);
}
memset(dp,0,sizeof(dp));
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
dp[i][j]=dp[i-1][j];
for(k=0;k<=j;k++)
{
dp[i][j]=max(dp[i][j],dp[i-1][j-k]+a[i][k]);
}
}
}
printf("%d\n",dp[n][m]);
}
return 0;
}
滚动数组:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int dp[105],a[105][105];
int max(int x,int y)
{
if(x>y)
return x;
return y;
}
int main()
{
int n,m,i,j,k;
while(scanf("%d %d",&n,&m),n+m)
{
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
scanf("%d",&a[i][j]);
}
memset(dp,0,sizeof(dp));
for(i=1;i<=n;i++)
{
for(j=m;j>=1;j--)
{
for(k=0;k<=j;k++)
{
dp[j]=max(dp[j],dp[j-k]+a[i][k]);
}
}
}
printf("%d\n",dp[m]);
}
return 0;
}