The Fewest Coins POJ - 3260

The Fewest Coins POJ - 3260

完全背包+多重背包。基本思路是先通过背包分开求出"付出"指定数量钱和"找"指定数量钱时用的硬币数量最小值,然后枚举找的钱,那么付出的钱也随之确定,对于每个枚举出的找的钱可以得到一个答案,那么枚举所有可能的找的钱取答案的最大值即可。

这里有一个对于找钱上限的证明。如果不知道,也可以随便搞一个(比如以下用的10000,注意空间,试过5000可以过)。

错误记录:

4.多重背包优化中,把除以2写成<<=2,WA

3.多重背包打了暴力的,没有加优化,TLE

2.dp数组初始化为0x3f3f3f3f,但是anss(最终答案)初始化为0x6fffffff,最后判anss!=0x6fffffff,但即使没有答案anss也会被0x3f3f3f3f更新,WA

1.枚举找钱只到了1000,WA

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 int n,m,T,v[110],c[110],p[11000],ans[21200],anss=0x3f3f3f3f;
 6 int main()
 7 {
 8     int i,j;
 9     scanf("%d%d",&n,&T);
10     memset(ans,0x3f,sizeof(ans));
11     memset(p,0x3f,sizeof(p));
12     for(i=1;i<=n;i++)
13         scanf("%d",&v[i]);
14     for(i=1;i<=n;i++)
15         scanf("%d",&c[i]);
16     p[0]=0;
17     for(i=1;i<=10000;i++)
18     {
19         for(j=1;j<=n;j++)
20             if(i>=v[j])
21                 p[i]=min(p[i],p[i-v[j]]);
22         p[i]++;
23     }
24     ans[0]=0;
25     for(i=1;i<=n;i++)
26     {
27         m=1;
28         while(c[i]>0)
29         {
30             if(m>c[i])    m=c[i];
31             c[i]=c[i]-m;
32             for(j=T+10000;j>=v[i]*m;j--)
33             {
34                 ans[j]=min(ans[j],ans[j-v[i]*m]+m);
35                 if(j>=T)
36                     anss=min(anss,ans[j]+p[j-T]);
37             }
38             m<<=1;
39         }
40     }
41     if(anss!=0x3f3f3f3f)
42         printf("%d",anss);
43     else
44         printf("-1");
45     return 0;
46 }
posted @ 2017-11-09 16:24  hehe_54321  阅读(211)  评论(0编辑  收藏  举报
AmazingCounters.com