【01背包】问题变形——饭卡

来源:互联网 发布:英语语法检测软件 编辑:程序博客网 时间:2024/04/30 13:43

Example:hdu 2546:http://acm.hdu.edu.cn/showproblem.php?pid=2546

解:利用“01背包”状态方程:F[v] = max(F[v], F[v-ci]+wi) 

(1)对这个问题来说,干扰项是最后的5元,可以买任何一道菜,所以可以先用5元买最贵的一道菜(反正买最后一道菜时至少要有5元余额,不如先不考虑这5元);去掉干扰项后就是一个“01”问题了。

(2)一道菜 i 的价格menu[i],既是“背包体积”,又是“背包价值”。

(3)最优子结构:value[i],表示“i元买菜,可以最多花几元”。

/***01背包问题变形*目标是找余额最少的情况,也就是花最多的情况*/#include <iostream>#include <algorithm>using namespace std;int Item[1002];int Value[1010];// Value[i]表示i元最多可以花多少template<class T>T max(const T &a, const T &b){  return a>b?a:b;}int main(){int n,W;while((cin>>n) && n){memset(Item, 0, sizeof(Item));for(int i=1; i<=n; i++)cin >> Item[i];// 价格(背包体积)sort(Item+1, Item+n+1);int maxItem = Item[n];// 把最大的一个菜买到cin >> W;// 余额(背包容量)for(int j=1; j<n; j++)// 每种物品或买或不买{for(int k=W; k>=Item[j]; k--)Value[k] = max(Value[k], Value[k-Item[j]]+Item[j]);}cout << (W-Value[W-5]) - maxItem << endl;}return 0;}



0 0