題意:一個商店提供多種商品,當使用者單獨購買商品時有一個價格,當使用者組合購買時可以獲得優惠,現在提供多種優惠方案和需要購買的物品總數,問最大的優惠是多少。
輸入
2
7 3 2
8 2 5
2
1 7 3 5
2 7 1 8 2 10
表示有 2 種商品,編號分別是 7 和 8,分別要購買的數量是 3 和 2,2 和 5 是它們的單件購買價格。
接下來是 2 種優惠。第 1 種優惠有 1 種商品:3 個 7 號商品價格為 5,第 2 種優惠是 2 種商品:1 個 7 號商品和 2 個 8 號商品價格是 10。
最多隻允許有 5 件商品。
用6進位表示所有狀態。
#define N 55int six[7] = {1,6,36,216,1296,7776};//因為最多隻有5種物品而且每種物品最多隻有5件,所以可以用6進位表示每種物品的狀態int index[1001];//吧編號都記錄為1,2,3,4...int dp[50000];int n,m;struct node{ int id; int num,p;}bask[10];struct node1{ int st; int p;}offer[100];int cal(int s){ int i; int sum = 0; for(i=0;i<n;i++){ sum += s%6*bask[i].p; s/=6; } return sum;}bool chk(int s1,int s2){//判斷狀態是否合法 int i; for(i=0;i<n;i++){ if(s1%6 + s2%6 > bask[i].num)return false; s1/=6,s2/=6; } return true;}int main(){ while(scanf("%d",&n) != -1){ int i,j; int state = 0; for(i=0;i<n;i++){ scanf("%d%d%d",&bask[i].id,&bask[i].num,&bask[i].p); index[bask[i].id] = i; state += six[i]*bask[i].num; } scanf("%d",&m); for(i=0;i<m;i++){ int k; scanf("%d",&k); offer[i].st = 0; while(k--){ int id,num; scanf("%d%d",&id,&num); offer[i].st += num*six[index[id]]; } scanf("%d",&offer[i].p); } for(i=0;i<=state;i++){ dp[i] = MAX; } dp[0] = 0; for(i=0;i<m;i++){ for(j=0;j+offer[i].st<=state;j++){ if(dp[j]!=MAX && chk(j,offer[i].st)){ if(dp[j+offer[i].st] > dp[j] + offer[i].p){ dp[j+offer[i].st] = dp[j] + offer[i].p;//對可以打折的組合進行dp } } } } int ans = MAX; for(i=0;i<=state;i++){ int sum = cal(state-i);//計算單件買的 ans = min(ans,dp[i]+sum); } printf("%d\n",ans); } return 0;}