您的位置:首页 > 其它

HDU 1074 Doing Homework

2016-01-18 18:39 369 查看
好难想到... ... 状态压缩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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: