宿題HDU-1074(状压dp)

Ignatiusは、30日のACM / ICPCから学校に戻ってきました。今、彼はやるべき多くの宿題を持っています。すべての教師は彼に宿題の提出期限を与えます。Ignatiusが締め切り後に宿題を提出した場合、教師は最終テストのスコアを1日1ポイントずつ減らします。そしてご存知のように、宿題を行うには常に長い時間がかかります。したがって、Ignatiusは、スコアの低下を最小限に抑えるために、宿題の順序を調整できるように支援してほしいと考えています。
入力
入力にはいくつかのテストケースが含まれています。入力の最初の行は、テストケースの数である単一の整数Tです。Tテストケースが続きます。
各テストケースは、宿題の数を示す正の整数N(1 <= N <= 15)で始まります。その後、N行が続きます。各行には、文字列S(被験者の名前。各文字列は最大100文字)と2つの整数D(被験者の期限)、C(この被験者の宿題を完了するまでに何日かかるか)が含まれます。

注:すべての件名はアルファベットの昇順で示されています。したがって、問題をはるかに簡単に処理できます。
出力
テストケースごとに、最小合計スコアの最小値を出力してから、1行に1つずつ、件名の順序を指定する必要があります。複数の注文がある場合は、アルファベットの小さいものを出力する必要があります。
サンプル入力
2
3
コンピューター3 3
英語20 1
数学3 2
3
コンピューター3 3
英語6 3
数学6 3
サンプル出力
2
コンピューター
数学
英語
3
コンピューター
英語
数学

ヒント
2番目のテストケースでは、コンピューター->英語->数学およびコンピューター->数学->英語の両方で3ポイントが減りますが、
「英語」という単語は「数学」という単語よりも前に表示されるため、最初の順序を選択します。これはいわゆるアルファベット順です。
アイデア:n = 15であるため、それほど大きくないため、すべての状態を列挙し、各状態の最小値を継続的に更新して、最終的にdp [(1 << n)-1]。具体的にはコードを参照してください。

#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;

const int maxx=16;
const int maxn=(1<<maxx);
struct node{
	string s;
	int ed,vl;
}p[maxx];
int dp[maxn],tme[maxn],pre[maxn],bk[maxn];
int n;

inline void init()
{
	memset(dp,0,sizeof(dp));
	memset(pre,-1,sizeof(pre));
	memset(tme,0,sizeof(tme));
}
inline void dfs(int x)
{
	if(x==0) return ;
	dfs(pre[x]);
	cout<<p[bk[x]].s<<endl;
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		for(int i=1;i<=n;i++) cin>>p[i].s>>p[i].ed>>p[i].vl;
		init();
		int All=1<<n;All-=1;
		int tmp,sum;
		for(int i=1;i<=All;i++)//枚举状态,这里枚举的就是每一种可能发生的情况
		{
			dp[i]=inf;
			for(int j=n;j>=1;j--)//正序的话,最小值计算的是没有问题的,但是无法按照题目要求的顺序输出
			{
				tmp=1<<(j-1);
				if(!(i&tmp)) continue;
				sum=tme[i-tmp]+p[j].vl-p[j].ed;//i-tmp,例如i=001010,tmp=001000,i-tmp=000010.就代表第五个作业先做,第三个作业再做。
				if(sum<0) sum=0;
				if(sum+dp[i-tmp]<dp[i])
				{
					dp[i]=dp[i-tmp]+sum;
					tme[i]=tme[i-tmp]+p[j].vl;
					pre[i]=i-tmp;
					bk[i]=j;
				}
			}
		}
		printf("%d\n",dp[All]);
		dfs(All);
	}
	return 0;
}

正直なところ、最初はプレッシャーになるとは思っていませんでした。
頑張って(o)/〜

652の元の記事を公開 101を獲得 50,000以上を表示

おすすめ

転載: blog.csdn.net/starlet_kiss/article/details/105451542