hdu 3348 coins
这道题算是一道很经典的题,很好的诠释了贪心和动态规划的不同功能。求最少钱的数量用贪心就够了,但是求最多钱的数量要用到动态规划的思想,每步都尽量保留最大
数量。具体看程序注解:
#include"iostream" #include"stdio.h" #include"algorithm" #include"string.h" #include"cmath" using namespace std; int fewest(int a[],int num[],int price) { int i; int ans=0; for(i=5;i>1;i--) { if(price>=num[i]*a[i]) { ans+=num[i]; price-=num[i]*a[i]; } else { ans+=price/a[i]; price%=a[i]; } } if(price>num[1])return -1; else return ans+price; } //这个函数的整体思想就是先保留全部的小钱,用大钱补缺,这样就可以得到最大数量 int largest(int a[],int num[],int price) { int i; int ans=0; int sum[6]; sum[1]=num[1]; for(i=2;i<6;i++) { sum[i]=sum[i-1]+a[i]*num[i]; } for(i=5;i>1;i--) { if(price<=sum[i-1])continue; else { int t; //先用满足条件的最大面值,如果有余数,所用张数+1, //不足的部分用较小面值的进行补 t=((price-sum[i-1])/a[i])+(((price-sum[i-1])%a[i])?1:0); ans+=t; price-=t*a[i]; } } return ans+price; } int main() { int t,price,i,j; int a[6]={0,1,5,10,50,100};//面值 int num[6];//数量 cin>>t; while(t--) { cin>>price; int sum=0; for(i=1;i<=5;i++) { cin>>num[i]; sum+=num[i]*a[i]; } if(sum<price) {cout<<"-1 -1"<<endl;continue;} int mi=fewest(a,num,price); if(mi==-1) {cout<<"-1 -1"<<endl;continue;} int mx=largest(a,num,price); cout<<mi<<" "<<mx<<endl; } return 0; }