现在的位置: 首页 > 综合 > 正文

USACO Section 3.3 Shopping Offers – 多重背包

2013年10月25日 ⁄ 综合 ⁄ 共 1429字 ⁄ 字号 评论关闭

    

    看题目所给的数据范围...最多5种物品..每个物品最多拿5个..那么实际上总状态数最多也就6^5=7776种..并且每种状态可以表示成一个5位的6进制数..每种优惠方案也可以表示成一个5位的6进制数...想到了这里题目就简单了..由于优惠方案是可以多次使用的...所以做一次多重背包可以搞定...我为了方便..就把每个状态都转化成了十进制数...这样感觉更加直观和方便...

/*  
ID: zzyzzy12   
LANG: C++   
TASK: shopping
*/      
#include<iostream>      
#include<istream>  
#include<stdio.h>      
#include<string.h>      
#include<math.h>      
#include<stack>  
#include<algorithm>      
#include<queue>   
#define oo 1000000000  
#define ll long long  
using namespace std;  
struct node
{
      int num,a[6][6],p;     
}s[105];
struct node1
{
      int p,k;      
}products[5];
int n,m,dp[80000],t[1005],goal,_6jie[6];
void make_dp()
{
      int h[5],i,j,y,x,temp;  
      memset(dp,0x7f,sizeof(dp));
      if (!m) { dp[goal]=0; return; }
      for (i=1;i<=goal;i++) 
      {
              y=0;  x=i;
              for (j=0;j<5;j++)
              { 
                     temp=x%6;
                     if (temp>products[j].k) goto A;
                     y+=temp*products[j].p;                 
                     x/=6;
              } 
              dp[i]=y;
              A: ;
      }   
      for (i=1;i<=n;i++)
      {
             temp=0;
             for (j=1;j<=s[i].num;j++)  temp+=_6jie[t[s[i].a[j][0]]]*s[i].a[j][1];
              if (dp[temp]>s[i].p) dp[temp]=s[i].p; 
             for (j=1;j<=goal-temp;j++)
               if (dp[j+temp]-dp[j]>s[i].p) 
                  dp[j+temp]=dp[j]+s[i].p; 
      }
}
int main()  
{  
      freopen("shopping.in","r",stdin);    
      freopen("shopping.out","w",stdout);  
      memset(products,0,sizeof(products));
      scanf("%d",&n);
      int i,j;
      for (i=1;i<=n;i++)
      {
             scanf("%d",&s[i].num);
             for (j=1;j<=s[i].num;j++) scanf("%d%d",&s[i].a[j][0],&s[i].a[j][1]);
             scanf("%d",&s[i].p);
      }
      _6jie[0]=1;
      for (i=1;i<6;i++) _6jie[i]=6*_6jie[i-1];
      goal=0;
      scanf("%d",&m);
      for (i=0;i<m;i++)
      {
             scanf("%d",&j);
             t[j]=i;
             scanf("%d%d",&products[i].k,&products[i].p);
             goal+=_6jie[i]*products[i].k; 
      } 
      make_dp();
      printf("%d\n",dp[goal]);
      return 0;     
}  

抱歉!评论已关闭.