HDU-1074 Doing Homework

Doing Homework

https://vjudge.net/problem/HDU-1074/origin

前言

第一次学状压 dp,它的思想和 dp 的思想一致,根据前一个状态来推取后一个状态。

就像这样 \(dp[11_2]=min(dp[10_2],dp[01_2])\)

使用二进制来进行表示状态。

\(000_2\) 表示一个物品也没有进行选择

\(001_2 = 0*2^2+0*2^1+1*2^0\) 表示选择了第 \(1\) 个物品

\(011_2 = 0*2^2+1*2^1+1*2^0\) 表示选择了第 \(1、2\) 个物品

\(101_2 = 1*2^2+0*2^1+1*2^0\) 表示选择了第 \(1、3\) 个物品


进而理解,选择第 \(x\) 个物品的时候,需要对前面没有选过 \(x\) 这个物品的状态进行求解最小值,而 \(((1<<x)\&pos)==0\) 表示 \(pos\) 这个状态没有进行选择物品 \(x\)

\(((1<<x)|pos)==0\) 表示在 \(pos\) 这个状态的基础上进行选择物品 \(x\)

进而对添加该物品的状态进行求最小值。

\(dp[(1<<x)|pos]=min(dp[pos]+val[x])\)

感觉应该可以理解,如果有不理解,希望大佬们在评论区询问。

\(Orz\)

题意:

\(T\) 组数据,每个数据有 \(n\) 个课程。

对于 \(n\) 个课程,包含三个属性课程名,作业的截止日期和完成作业需要的天数。

作业完成情况拖延一天结果就是扣一定分数。

题解

通过状压 \(dp\) 进行求解,

在枚举状态的时候需要保存它的前一个状态。

之后使用 \(dfs\) 进行求出所有解。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int INF = 0x3f3f3f3f;
struct node{
	char s[105];
	int l,r;
}num[20];
int dp[1<<16];
int pre[1<<16];
bool cmp(node x,node y){
	int lx=strlen(x.s);
	int ly=strlen(y.s);
	for(int i=0;i<lx&&i<ly;++i){
		if(x.s[i]==y.s[i]);
		else return x.s[i]<y.s[i];
	}
	return lx<ly;
}
void dfs(int pos,int n){
	if(!pos)return;
	int x;
	for(int i=0;i<n;++i){
		if(((1<<i)&pos)&&!(pre[pos]&(1<<i))){
			x=i;
		}
	}
	dfs(pre[pos],n);
	printf("%s\n",num[x].s);
}
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		int n;
		memset(dp,INF,sizeof(dp));
		scanf("%d",&n);
		for(int i=0;i<n;++i){
			scanf("%s%d%d",num[i].s,&num[i].l,&num[i].r);
		}
		// sort(num,num+n,cmp);
		// for(int i=0;i<n;++i)
		// 	printf("%s\n",num[i].s);
		dp[0]=0;
		for(int i=0;i<(1<<n);++i){
			for(int j=0;j<n;++j){
				if((1<<j)&i)continue;
				int val=num[j].r;
				for(int k=0;k<n;++k){
					if((1<<k)&i)
						val+=num[k].r;
				}
				val=val>num[j].l?val-num[j].l:0;
				if(dp[(1<<j)|i]>dp[i]+val){
					dp[(1<<j)|i]=dp[i]+val;
					pre[(1<<j)|i]=i;
				}
			}
		}
		printf("%d\n",dp[(1<<n)-1]);
		dfs((1<<n)-1,n);
	}
	return 0;
}

后记

这个题好像有点问题诶,题目最后要求的是按字典序进行输出,因为怕 \(WA\) 预处理了一下所有物品 \(A\) 了,但是把预处理关了也过了。

仿佛所有的解只有一个结果不需要进行处理的诶。

posted @ 2020-04-18 09:17  VagrantAC  阅读(94)  评论(0编辑  收藏  举报