饭卡 HDU - 2546
考察:01背包
这道题懵逼半天,看了大佬的代码终于懂了点
思路:
这道题是和购买顺序有关的,我们先拿出最贵的菜,同时余额拿出5元,在剩余的余额尽可能买总和贵的菜.买完最后余额拿出的5元再买最贵的菜,这就是正解了....
也因为这道题搞明白了点01背包的板子.f[i][j]表示在j余额条件下,前i个物品所能达到的最大价值.这道题如果设置f[i][j]==余额的话,表示的是在前i个菜,买前j余额在买后能达到的最小余额.属性值和j的含义重复给我搞懵了..果然还是太菜啊
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int N = 1010; int a[N],f[N]; int main() { int n,m; while(scanf("%d",&n)&&n) { memset(f,0,sizeof f); for(int i=1;i<=n;i++) scanf("%d",&a[i]); sort(a+1,a+n+1); scanf("%d",&m); if(m<5) { printf("%d\n",m); continue;} m-=5; for(int i=1;i<=n-1;i++) for(int j=m;j>=a[i];j--) { f[j] = max(f[j],f[j-a[i]]+a[i]); } printf("%d\n",m+5-f[m]-a[n]); } return 0; }