poj1170 状态压缩

来源:互联网 发布:黑客如何入侵网络 编辑:程序博客网 时间:2024/06/05 14:43

因为每种物品最多五个,总共五种物品,所以可以将状态存为6进制的整数。

先对每一种special offer进行dp, 转移方程为  dp[ i + offfer[k].stt ] = MIN( dp[ i + offer[k].stt , dp[ i ] + offer[k].prc ), 当然状态转移前,要进行判断是否可转移,

若当前状态下 的某种物品数量加上当前的special offer中的这种物品数量后,超过总共拥有这种物品的数量,此时是不可转移的。

#include <iostream>#include <cmath>using namespace std;#define M 6struct Item{int num, prc; //num为每种物品的数量,prc为单价} items[5];struct Offer{int stt, prc; //stt是将每一种special offer中各种物品压缩成的状态,prc为对应的优惠价} offer[100];int hash[1000]; //hash[k]的值为product code为k的物品的下标int dp[8000];inline int MIN(int a, int b){return a > b ? b : a;} //判断当前状态为state时,加上stt(stt为special offer)后,每一种物品是否超过 //这种物品的总数,若超过,则当前状态不能靠这个stt进行转移bool check(int state, int stt) {    int id = 0;while(state > 0 && stt > 0){     if(state % M + stt % M > items[id].num) return false; state /= M; stt /= M; id++;}return true;}int cal_left(int state){int left = 0, id = 0;        while(state > 0){   left += (state % M) * items[id].prc;   state /= M;   id++;}return left;}int main(){int state;    int b, s, n;    int i, j;    int code, num;state = 0;memset(hash, -1, sizeof(hash));scanf("%d", &b);for(i = 0; i < b; i++){  scanf("%d%d%d", &code, &items[i].num, &items[i].prc);hash[code] = i; state += items[i].num * (int)pow(6.0, i*1.0); //篮子里的所有物品压缩为状态state}        scanf("%d", &s);for(i = 0; i < s; i++){offer[i].stt = 0;scanf("%d", &n);for(j = 0; j < n; j++){scanf("%d%d", &code, &num);offer[i].stt += (int)pow(6.0, hash[code]*1.0) * num; //压缩special offer}scanf("%d", &offer[i].prc);}    for(i = 1; i <= state; i++) dp[i] = INT_MAX;dp[0] = 0; //注意初始化    for(i = 0; i <= state; i++){if(dp[i] == INT_MAX) continue;for(j = 0; j < s; j++){if(i+offer[j].stt <= state && check(i, offer[j].stt)){  //状态之间可以直接相加(以前我不知道这点),判断是否可转移    dp[i+offer[j].stt] = MIN(dp[i+offer[j].stt], dp[i]+offer[j].prc);}}}//计算剩余的按原价购买的物品与通过special offer购买的物品的总价格//最小值即为答案int ans = INT_MAX;for(i = 0; i <= state; i++){         if(dp[i] == INT_MAX) continue;ans = MIN(ans, dp[i] + cal_left(state-i)); }printf("%d\n", ans);return 0;}


 

原创粉丝点击