• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            pku 1170 Shopping Offers 狀態DP或者說最短路都可以


            看圖說話,描述題目- -
            有若干類商品,然后每個商品有一定的價格,商店推出捆綁銷售優惠,購買指定組合的物品可以有一定的優惠。
            給出目標狀態,要求花最少的錢買到指定數量的物品。
            由于數據量很小,很快想到壓縮狀態,然后DP求從初始狀態到末狀態的最小花費。
            這種題目我喜歡轉化為圖,把每個狀態看作一個節點,然后求這個圖上從起點到終點的最長鏈。對于某些看似存在后效性的狀態DP中,可以采用SPFA算法,消除后效性。
            貼代碼
              1 # include <cstdio>
              2 # include <cstring>
              3 using namespace std;
              4 int dp[100000];
              5 # define encode(n1,n2,n3,n4,n5) (((((((((n1)<<3)|(n2))<<3)|(n3))<<3)|(n4))<<3)|(n5))
              6 # define getn1(sta) ((sta)>>12)
              7 # define getn2(sta) (((sta)>>9)&7)
              8 # define getn3(sta) (((sta)>>6)&7)
              9 # define getn4(sta) (((sta)>>3)&7)
             10 # define getn5(sta) ((sta)&7)
             11 # define min(a,b) ((a)<(b)?(a):(b))
             12 int pri[200][2],count=0;
             13 int solve(int pos)
             14 {
             15    if(dp[pos]!=-1return dp[pos];
             16    else if(pos==0return 0;
             17    else
             18    {
             19      //  int show1=getn1(pos),show2=getn2(pos),show3=getn3(pos),show4=getn4(pos),show5=getn5(pos);
             20        int minnum=0xfffffff;
             21        for(int i=count-1;i>=0;i--)
             22           if(getn1(pos)-getn1(pri[i][0])>=0&&
             23              getn2(pos)-getn2(pri[i][0])>=0&&
             24              getn3(pos)-getn3(pri[i][0])>=0&&
             25              getn4(pos)-getn4(pri[i][0])>=0&&
             26              getn5(pos)-getn5(pri[i][0])>=0&&
             27              solve(encode(getn1(pos)-getn1(pri[i][0]),getn2(pos)-getn2(pri[i][0]),getn3(pos)-getn3(pri[i][0]),getn4(pos)-getn4(pri[i][0]),getn5(pos)-getn5(pri[i][0])))+pri[i][1]<minnum)
             28                 minnum=solve(encode(getn1(pos)-getn1(pri[i][0]),getn2(pos)-getn2(pri[i][0]),getn3(pos)-getn3(pri[i][0]),getn4(pos)-getn4(pri[i][0]),getn5(pos)-getn5(pri[i][0])))+pri[i][1];
             29        dp[pos]=minnum;
             30        return minnum;
             31    }
             32 }
             33 int main()
             34 {
             35   //  FILE *in1=fopen("input.txt","r"),*in2=fopen("offer.txt","r");
             36   //  FILE *out=fopen("output.txt","w");
             37     int num,co=1;
             38     int map[1000];
             39     memset(map,-1,sizeof(map));
             40     memset(dp,-1,sizeof(dp));
             41     scanf("%d",&num);
             42     int ori=0;
             43     while(num--)
             44     {
             45        int c,k,p;
             46        scanf("%d%d%d",&c,&k,&p);
             47        if(map[c]==-1) map[c]=co++;
             48        c=map[c];
             49        switch(c)
             50        {
             51          case 1:       
             52             pri[count][0]=encode(1,0,0,0,0);
             53             ori|=encode(k,0,0,0,0);
             54             break;
             55          case 2:
             56             pri[count][0]=encode(0,1,0,0,0);
             57             ori|=encode(0,k,0,0,0);
             58             break;
             59          case 3:
             60             pri[count][0]=encode(0,0,1,0,0);
             61             ori|=encode(0,0,k,0,0);
             62             break;
             63          case 4:
             64             pri[count][0]=encode(0,0,0,1,0);
             65             ori|=encode(0,0,0,k,0);
             66             break;
             67          case 5:
             68             pri[count][0]=encode(0,0,0,0,1);
             69             ori|=encode(0,0,0,0,k);
             70             break;
             71        };
             72        pri[count++][1]=p;   
             73     }
             74     scanf("%d",&num);
             75     while(num--)
             76     {
             77        int n;
             78        pri[count][0]=0;
             79        bool flag=true;
             80        scanf("%d",&n);
             81        while(n--)
             82        {
             83           int c,k;
             84           scanf("%d%d",&c,&k);
             85           if(map[c]==-1)
             86              flag=false;
             87           if(flag)
             88           {
             89                switch(map[c])
             90                {
             91                  case 1:       
             92                     pri[count][0]|=encode(k,0,0,0,0);
             93                     break;
             94                  case 2:
             95                     pri[count][0]|=encode(0,k,0,0,0);
             96                     break;
             97                  case 3:
             98                     pri[count][0]|=encode(0,0,k,0,0);
             99                     break;
            100                  case 4:
            101                     pri[count][0]|=encode(0,0,0,k,0);
            102                     break;
            103                  case 5:
            104                     pri[count][0]|=encode(0,0,0,0,k);
            105                     break;
            106                };
            107           }
            108        }
            109        scanf("%d",&n);
            110        if(flag)
            111            pri[count++][1]=n;
            112     }
            113    // for(int i=0;i<count;i++)
            114      // printf("%d %d %d %d %d\n",getn1(pri[i][0]),getn2(pri[i][0]),getn3(pri[i][0]),getn4(pri[i][0]),getn5(pri[i][0]));
            115     //printf("%d %d %d %d %d\n",getn1(ori),getn2(ori),getn3(ori),getn4(ori),getn5(ori));
            116     printf("%d\n",solve(ori));
            117    // fclose(in1);
            118     //fclose(in2);
            119    // fclose(out);
            120     return 0;
            121     
            122 }
            123 


            posted on 2010-10-22 01:59 yzhw 閱讀(146) 評論(0)  編輯 收藏 引用 所屬分類: DP

            <2010年11月>
            31123456
            78910111213
            14151617181920
            21222324252627
            2829301234
            567891011

            導航

            統計

            公告

            統計系統

            留言簿(1)

            隨筆分類(227)

            文章分類(2)

            OJ

            最新隨筆

            搜索

            積分與排名

            最新評論

            閱讀排行榜

            99久久精品免费| 91精品国产综合久久香蕉| 久久婷婷五月综合成人D啪| 欧美日韩精品久久久久| 久久综合狠狠综合久久97色| 要久久爱在线免费观看| 久久综合狠狠综合久久综合88| 97久久国产露脸精品国产| 久久电影网2021| 久久噜噜电影你懂的| 人人妻久久人人澡人人爽人人精品| 久久精品一本到99热免费| 久久精品成人免费国产片小草| 久久人人爽人人爽人人AV| 日产精品99久久久久久| 久久综合久久综合久久综合| 久久WWW免费人成一看片| 日韩欧美亚洲国产精品字幕久久久| 亚洲国产精品综合久久网络 | 性欧美大战久久久久久久| 久久精品国产72国产精福利| 久久久精品国产sm调教网站| 久久99国产精品久久99小说| 97超级碰碰碰碰久久久久| 国产欧美一区二区久久| 久久亚洲AV成人无码国产 | 久久久久亚洲AV成人片| 青青草原综合久久| 97精品伊人久久大香线蕉app| 少妇高潮惨叫久久久久久| 国产成人综合久久精品红| 亚洲另类欧美综合久久图片区| 久久91精品综合国产首页| 色综合久久中文色婷婷| 久久精品国产91久久麻豆自制| 久久精品国产亚洲AV香蕉| 久久人爽人人爽人人片AV| 久久国产乱子伦免费精品| 99久久99久久久精品齐齐| 精品久久久久久中文字幕| 国产精品欧美久久久天天影视|