poj 1170 Shopping Offers
题意:
给出若干种货物及其数量以及价格,然后给出一些优惠信息,一些货物组合在一起的价格一定比它们的原价加起来要低。
现在买到这些货物最少的钱(不能增加货物,即使钱会更少)。
思路:
最多有5种货物,每种货物最多5个。
那么就可以考虑压缩状态,6进制的状态压缩,这样就可以表示每种货物的状态。
然后,对于每一种优惠信息,可以在输入的时候就将其压缩为一种状态,节省大量的时间。
如果说对于所有的优惠信息都不满足的时候,那么就把原价当作优惠信息进行处理,这样即使所有的优惠信息都无法转移,那么原价是一定可以转移的。
dp[i] = min(d[i],dp[j]+cut[k]),i和j均满足输入限制,即所有物品的数量都小于等于输入。
代码:
1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 #include <map> 5 #include <vector> 6 using namespace std; 7 const int N = 50000; 8 const int inf = 0x3f3f3f3f; 9 struct node 10 { 11 int id,cnt; 12 node(){}; 13 node(int a,int b) 14 { 15 id = a; 16 cnt = b; 17 } 18 }; 19 int dp[N]; 20 int num[20],prc[20],dic[200]; 21 int ps[10]; 22 map<int,int> mmp; 23 int js[200]; 24 int main() 25 { 26 int n; 27 ps[0] = 1; 28 for (int i = 1;i < 10;i++) ps[i] = 6*ps[i-1]; 29 scanf("%d",&n); 30 mmp.clear(); 31 memset(dp,inf,sizeof(dp)); 32 memset(js,0,sizeof(js)); 33 for (int i = 0;i < n;i++) 34 { 35 int c,k,p; 36 scanf("%d%d%d",&c,&k,&p); 37 num[i] = k; 38 prc[i] = p; 39 mmp[c] = i; 40 } 41 int s; 42 scanf("%d",&s); 43 for (int i = 0;i < s;i++) 44 { 45 int t; 46 scanf("%d",&t); 47 for (int j = 0;j < t;j++) 48 { 49 int x,y; 50 scanf("%d%d",&x,&y); 51 js[i] += ps[mmp[x]] * y; 52 } 53 scanf("%d",&dic[i]); 54 } 55 for (int i = 0;i < n;i++) 56 { 57 for (int j = 1;j <= num[i];j++) 58 { 59 js[s] = ps[i] * j; 60 dic[s] = prc[i] * j; 61 s++; 62 } 63 } 64 dp[0] = 0; 65 int mmz = 0; 66 for (int i = 0;i < n;i++) mmz += ps[i]*num[i]; 67 for (int i = 0;i <= mmz;i++) 68 { 69 for (int j = 0;j < s;j++) 70 { 71 if (dp[i] >= inf) continue; 72 int mz = i + js[j]; 73 int tmp = mz; 74 int ct = 0; 75 bool f = 0; 76 while (tmp) 77 { 78 if (tmp % 6 > num[ct]) f = 1; 79 tmp /= 6; 80 ct++; 81 } 82 if (f) continue; 83 dp[mz] = min(dp[mz],dp[i] + dic[j]); 84 } 85 } 86 printf("%d\n",dp[mmz]); 87 return 0; 88 }
康复训练中~欢迎交流!