HDU 1074 Doing Homework

好难想到... ... 状态压缩DP,写的较搓

#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<vector>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;

const int maxn=15;
string CMP[40000];
struct X
{
    string name;
    int d,c;
} s[maxn];
int n,T,State;
int dp[40000],add[40000];
int BaseA[20],totA;
int BaseB[20],totB;
stack<int>S;

void ToA(int x)
{
    totA=0;
    memset(BaseA,0,sizeof BaseA);
    while(x)
    {
        BaseA[totA++]=x%2;
        x=x/2;
    }
}

void ToB(int x)
{
    totB=0;
    memset(BaseB,0,sizeof BaseB);
    while(x)
    {
        BaseB[totB++]=x%2;
        x=x/2;
    }
}

int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        State=(1<<n)-1;
        for(int i=0; i<n; i++)
        {
            cin>>s[i].name;
            scanf("%d%d",&s[i].d,&s[i].c);
        }
        for(int i=0;i<=39000;i++)
            dp[i]=0x7fffffff,add[i]=-1,CMP[i].clear();
        dp[0]=0;
        for(int i=1;i<=State;i++)
        {
            ToA(i);
            for(int j=0;j<n;j++)
            {
                if(BaseA[j])
                {
                    int preState=i-(int)pow(2.0,j);
                    ToB(preState);

                    int cost1=0;
                    for(int k=0;k<totB;k++)
                        if(BaseB[k]) cost1=cost1+s[k].c;
                    cost1=cost1+s[j].c;
                    int C;
                    if(cost1<s[j].d) C=dp[preState];
                    else C=dp[preState]+cost1-s[j].d;

                    if(C<dp[i])
                    {
                        dp[i]=C,add[i]=j;
                        char sign=j+'a';
                        CMP[i]=CMP[preState]+sign;
                    }
                    //保证字典序
                    else if(C==dp[i])
                    {
                        char sign=j+'a';
                        string r=CMP[preState]+sign;
                        if(r<CMP[i])
                        {
                            add[i]=j;
                            CMP[i]=r;
                        }
                    }
                }
            }
        }
        printf("%d\n",dp[State]);
        while(!S.empty()) S.pop();
        int nowState=State;
        while(1)
        {
            S.push(add[nowState]);
            nowState=nowState-(int)pow(2.0,add[nowState]);
            if(nowState==0) break;
        }
        while(!S.empty())
        {
            cout<<s[S.top()].name<<endl;
            S.pop();
        }
    }
    return 0;
}

 

posted @ 2016-01-18 18:39  Fighting_Heart  阅读(156)  评论(0编辑  收藏  举报