这是一道简单的分组背包,因为每种课可以有多种选择:花几天时间在该课上。一旦作出选择,就不能再选该课,就相当于有多组物品,每组内的物品互相冲突,最多只能选一件。
开始我对数组val的每一个元素,算出其价值与天数之比,将每一种课内,比值最大的选出来,这样每种课就只有一个选择,从而转化为01背包,但是提交之后WA了,于是我改用分组背包的标准解法,即
for 所有的组k for v=V..0 for 所有的i属于组k f[v]=max{f[v],f[v-c[i]]+w[i]}
这样的确能够AC,但是我想知道为什么第一种方法不可行
下面分别是第一种和第二种方法的代码。
/*算比率*/
#include<stdio.h> #include<string.h> #define MAX_COURSES 110 int get_max(int,int),daysSelectedValue[MAX_COURSES],cost[MAX_COURSES],val[MAX_COURSES][MAX_COURSES]; void mkchoice(int,int); int main() { int n,m; while(scanf("%d%d",&n,&m)!=EOF&&!(n==0&&m==0)) { int i,j,dp[MAX_COURSES]; memset(val,0,sizeof(val)); for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { scanf("%d",&val[i][j]); // j days on the ith course:value } } memset(dp,0,sizeof(dp)); for(i=1;i<=n;i++) { for(j=m;j>=cost[i];j--) { dp[j]=get_max( dp[j],dp[j-cost[i]]+daysSelectedValue[i]); } } printf("%d\n",dp[m]); } return 0; } int get_max(int x,int y) { return x>y?x:y; } void mkchoice(int n,int m) { double rate=0; int i,j,recrdDays,recrdVal; for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { double tem=(double)val[i][j] / (double)j ; if( rate<tem ) { rate=tem; recrdDays=j; recrdVal=val[i][j]; } } cost[i]=j; daysSelectedValue[i]=recrdVal; } }
第二种方法
#include<stdio.h> #include<string.h> #define MAX_COURSES 110 int get_max(int,int),val[MAX_COURSES][MAX_COURSES]; void mkchoice(int,int); int main() { int n,m; while(scanf("%d%d",&n,&m)!=EOF&&!(n==0&&m==0)) { int i,j,k,dp[MAX_COURSES]; memset(val,0,sizeof(val)); for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { scanf("%d",&val[i][j]); } } memset(dp,0,sizeof(dp)); for(i=1;i<=n;i++) { for(j=m;j>0;j--) { for(k=1;k<=m;k++) { if(j-k>=0) dp[j]=get_max(dp[j],dp[j-k]+val[i][k]); } } } printf("%d\n",dp[m]); } return 0; } int get_max(int x,int y) { return x>y?x:y; }