题目大意:电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额。如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后卡上余额为负),否则无法购买(即使金额足够)。所以大家都希望尽量使卡上的余额最少。
某天,食堂中有n种菜出售,每种菜可购买一次。已知每种菜的价格以及卡上的余额,问最少可使卡上的余额为多少。
解题思路;按照贪心的思想,菜的价格就要从小到达排,因为要以最小的钱(大于等于5)买最贵的菜,那样才会使余额达到最小
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1010;
const int INF = 0x3f3f3f3f;
int n, m;
int num[N];
bool vis[N];
bool cmp(const int &a, const int &b) {
return a < b;
}
void init() {
for (int i = 0; i < n; i++)
scanf("%d", &num[i]);
scanf("%d", &m);
sort(num, num + n, cmp);
}
void solve() {
if (m < 5) {
printf("%d\n", m);
return ;
}
memset(vis, 0, sizeof(vis));
vis[m] = true;
int ans = INF;
for (int i = 0; i < n; i++) {
for (int j = 5; j <= m; j++) {
if (vis[j]) {
if (j - num[i] >= 5) vis[j - num[i]] = true;
ans = min(j - num[i], ans);
}
else {
if (j + num[i] <= m && vis[j + num[i]]) vis[j] = true;
}
}
}
printf("%d\n", ans);
}
int main() {
while (scanf("%d", &n) != EOF && n) {
init();
solve();
}
return 0;
}