类似01背包。用hs[n]= 1表示是否可达。
可以证明如果饭卡的钱大于5的话,必然会点价格最高的菜。
所以问题转化为求m-5范围内点菜。越接近越好。这就是01背包。。
#include <iostream>
using namespace std;
const int N = 1105;
int hs[N];
int price[N];
int main()
{
int n, m;
while(scanf("%d", &n), n)
{
memset(hs, 0, sizeof(hs));
for(int i = 0; i < n; i++)
scanf("%d", &price[i]);
scanf("%d", &m);
if(m < 5)
{
cout << m << endl; //不小心写成cout<<5<< endl; WA了半天才找到问题
continue;
}
int max = -1;
int index = -1;
for(int i = 0;i < n; i++) //选出价格最高的菜
{
if(price[i] > max)
{
max = price[i];
index = i;
}
}
hs[0] = 1;
for(int i = 0; i < n; i++) //cai
{
if(i == index)
continue;
//for(int j = 0; j <= m - 5; j++) //注意这个错误
for(int j = m-5; j >= 0; j--)
{
if(hs[j] == 1)
hs[j+price[i]] = 1;
}
}
int money;
for(money = m-5; money >= 0; money--)
if(hs[money] == 1)
break;
cout << m - money - max << endl;
}
return 0;
}