题意:给出菜的价钱和自己的余额。使自己余额最少,注意余额大于5的情况可以买任意的菜。
思路:小于5的余额不能买菜,直接输出,大于五的余额,留下5元买最贵的菜,剩下的余额进行01背包,将剩下的余额减去01背包消耗金额最大。就得出答案
代码:
#include<iostream> #include<cstdio> using namespace std; int ZeroOnePack( int price[],int money,int n ,int pos) //01背包解法 { int f[1024]={0}; for( int i=1; i<=n ; i++ ) { if(i != pos) for( int j=money ; j>=price[i]; j-- ) { if(f[j]<f[j-price[i]]+price[i] ) f[j]=f[j-price[i]]+price[i]; } } return money-f[money]; } int main( ) { int n,money,price[1024]; while( scanf( "%d",&n )==1 && n ) { int max=0,pos; for( int i=1; i<=n; i++) { scanf( "%d" ,&price[i] ); if( max<price[i] ) //记录最贵的菜的下标 { pos=i; max=price[i]; } } scanf( "%d",&money ); if( money>=5 ) printf( "%d ",ZeroOnePack( price,money-5,n ,pos)-max+5); //需要预留5元买最贵的菜。money-5 else printf( "%d ",money ); } return 0; }