题意:给6种不同面额硬币,求组成[1,100]中数的平均需要硬币与最多需要硬币数,可以通过减法获得,比如有1、4两种硬币,凑成3可以用4-1两个硬币完成,而不是1+1+1三个硬币。
题解:背包问题,由于可以减,还需要反过来dp一遍,值得注意的是上界需要设成2000才行。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 int dp[2050]; 6 void update(int v) 7 { 8 if(v>0) 9 for(int i=0;i+v<=2000;i++) 10 dp[i+v]=min(dp[i+v],dp[i]+1); 11 else 12 for(int i=2000;i+v>=0;i--) 13 dp[i+v]=min(dp[i+v],dp[i]+1); 14 } 15 int main() 16 { 17 int T; 18 for(scanf("%d",&T);T;T--) 19 { 20 dp[0]=0; 21 for(int i=1;i<=2000;i++) 22 dp[i]=100000; 23 int a[10]; 24 for(int i=0;i<6;i++) 25 scanf("%d",a+i),update(a[i]); 26 for(int i=0;i<6;i++) 27 update(-a[i]); 28 int ans=0,num=0; 29 for(int i=1;i<=100;i++) 30 ans+=dp[i],num=max(num,dp[i]); 31 printf("%.2lf %d\n",ans/100.0,num); 32 } 33 return 0; 34 }