poj1170 状态压缩背包

来源:互联网 发布:淘宝推广视频百度云 编辑:程序博客网 时间:2024/06/06 18:29

看到题目就想到5维背包,不过想了想状态转移要5层循环,写起来相当痛苦。也没想到6进制,看了一下讨论说用六进制,想了一下似乎还真是这样,状态转换好写起来就简单,直接背包就可以。


ACcode:


#include<cstdio>#include<cstring>const int NS=6;const int MAX=7776;const int INF=1<<30;struct offer{    int st,p;    void inpt(int xa,int xb){        st=xa,p=xb;    }}s[110];int n,top,ans;int x,y,z,m,num;int p6[NS];int h[1000];int dp[MAX];int bit[MAX][5];void prepare(){    p6[0]=1;    for (int i=1;i<NS;i++)    p6[i]=p6[i-1]*6;    for (int i=0;i<MAX;i++)    for (int t=i,j=0;j<5;j++)    bit[i][j]=t%6,t/=6;}int judge(int s1,int s2){    for (int i=0;i<5;i++)    if (bit[s2][i]>bit[s1][i]) return 0;    return 1;}int Min(int xa,int xb){    return xa<xb?xa:xb;}int main(){    prepare();    while (~scanf("%d",&n))    {        top=ans=dp[0]=0;        for (int i=0;i<n;i++)        {            scanf("%d%d%d",&x,&y,&z);            ans+=y*p6[i],h[x]=i;            s[top++].inpt(p6[i],z);        }        scanf("%d",&m);        for (int i=0;i<m;i++)        {            scanf("%d",&num),z=0;            for (int j=0;j<num;j++)            scanf("%d%d",&x,&y),z+=p6[h[x]]*y;            scanf("%d",&x); s[top++].inpt(z,x);        }        for (int i=1;i<=ans;i++)        {            dp[i]=INF;            for (int j=0;j<top;j++)            if (judge(i,s[j].st))            dp[i]=Min(dp[i],dp[i-s[j].st]+s[j].p);        }        printf("%d\n",dp[ans]);    }    return 0;}

原创粉丝点击