m Type_1:price_1 Type_2:price_2 ... Type_m:price_m
其中正整數 m 是這張發票上所開物品的件數,Type_i 和 price_i 是第 i 項物品的種類和價值。物品種類用一個大寫英文字母表示。當N爲0時,全部輸入結束,相應的結果不要輸出。
0—1揹包,把每張發票當一個物品, 其中,發票中有單項大於600的或者總額大於1000的,這張發票扔掉不要,也就是不加入物品的行列。整理出每張發票的總額,作爲這件物品的價值也作爲容量(相當於物品的體積),放到容量爲q的揹包中,這就是標準的0—1揹包了;
轉移方程:f[j]=max(f[j],f[j-1]+v[i]);
代碼:
#include <stdio.h>
#include <string.h>
int max(int a,int b)
{
if(a>b)
return a;
return b;
}
int dp[3000010];
int main()
{
int n,i,j,m,flag,len;
double q,val;
int w[35];
int w1[3];
char ch;
while (scanf("%lf%d",&q,&n)!=EOF&&n)
{
memset(dp,0,sizeof(dp));
len = 0;
for (i=0;i<n;i++)
{
scanf("%d",&m);
flag = 1;
for(j=0;j<3;j++)
w1[j] = 0;
j = 0;
while (m--)
{
getchar();
scanf("%c:%lf",&ch,&val);
if(ch>='A'&&ch<='C')
{
j = ch-'A';
w1[j]+=(int)(val*100);
}
/*不可報銷條件*/
if(w1[j]>60000||w1[0]+w1[1]+w1[2]>100000||ch!='A'&&ch!='B'&&ch!='C')
flag = 0;
}
if (flag)
w[len++] = w1[0]+w1[1]+w1[2];
}
for (i=0;i<len;i++)
{
for (j=(int)(q*100);j>=w[i];j--)
dp[j] = max(dp[j],dp[j-w[i]]+w[i]);
}
printf("%.2lf\n",(double)(dp[(int)(q*100)]/100.0));
}
return 0;
}