POJ 1252 Euro Efficiency 完全背包
http://poj.org/problem?id=1252
题意:给出六种币值的硬币,尽量用少得数量组合出(1~100)的币值,输出用的硬币的平均数量和用到的最多组合时的数量
有一点,不是所有的组合都是六种硬币相加得到的,还有相减的情况,如有 1、2、5、10、20、50六种硬币,
98=50+20+20+5+2+1 , 98=50+50-2 后一种才是答案
代码:
#include<iostream> #include<cstdio> #include<string> #include<cstring> #define inf 10005 const int MAX=2002; using namespace std; int a[7],dp[MAX]; int min(int a,int b) { return a<b?a:b; } int main() { int CASE; int i,j,k; scanf("%d",&CASE); while(CASE--) { for(i=1;i<=6;i++) scanf("%d",&a[i]); for(i=0;i<=MAX;i++) dp[i]=inf; dp[0]=0; for(j=1;j<=6;j++)//完全背包 for(k=a[j];k<=MAX;k++) { dp[k]=min(dp[k],dp[k-a[j]]+1); } for(k=1;k<=6;k++)//保证大数用的硬币最少,然后从大往小减,还是完全背包的思想 for(j=MAX-a[k];j>=1;j--) //for(i=j-a[k];i>=0;i--)//完全背包,减掉一维,运行时间减少300+MS dp[j]=min(dp[j],dp[j+a[k]]+1); double ans=0; int MIN=0; for(i=1;i<=100;i++) { ans+=dp[i]; MIN=MIN>dp[i]?MIN:dp[i]; } ans/=100; printf("%.2f %d\n",ans,MIN); } return 0; }