!HDU 1074 Doing Homework--DP--(状态压缩)

题意:n个作业,每个作业有deadline和做完这个作业需要花的时间cost,完成作业每超过一天就减一分,求减去的最小的分数

分析:作业的全排列中取最优解,但是15!太大了会超时,所以用二进制来状态压缩,15个二进制位,第i位的0/1代表第i个作业是否完成。

1.会用状态压缩

2.保存和输出最优解序列方法

慢慢加深理解吧

代码:

#include<iostream>
#include<cstring>
#include<string>
#define INF 1<<16
using namespace std;
int t,n;
struct node1{
    string chr;
	int ddl,cost;
}a[16];
struct node2{
	int pre,reduced,days;
}dp[INF];
int vis[INF];
void Output(int i)
{
	int tmp=dp[i].pre^i;
	int cnt=0;
	tmp>>=1;
	while(tmp){
		cnt++;
		tmp>>=1;
	}
	if(dp[i].pre!=0) Output(dp[i].pre);
	cout<<a[cnt].chr<<endl;
}
int main()
{
	cin>>t;
	while(t--){
		memset(vis,0,sizeof(vis));
		cin>>n;
		for(int i=0;i<n;i++) cin>>a[i].chr>>a[i].ddl>>a[i].cost;
		dp[0].pre=-1,dp[0].days=0,dp[0].reduced=0;
		vis[0]=1;
		int en=(1<<n)-1;
		for(int i=0;i<en;i++){
			for(int j=0;j<n;j++){
				int tmp=1<<j;
				if((i&tmp)==0){
					int tmp2=i|tmp;
					int day=dp[i].days+a[j].cost;
					dp[tmp2].days=day;
					int reduce=day-a[j].ddl;
					if(reduce<0) reduce=0;
					reduce+=dp[i].reduced;
					if(vis[tmp2]){
						if(reduce<dp[tmp2].reduced){
							dp[tmp2].reduced=reduce;
							dp[tmp2].pre=i;
						}
					}
					else{
						vis[tmp2]=1;
						dp[tmp2].reduced=reduce;
						dp[tmp2].pre=i;
					}
				}
			}
		}
		cout<<dp[en].reduced<<endl;
		Output(en);
	}
}
时间: 2024-10-21 05:19:25

!HDU 1074 Doing Homework--DP--(状态压缩)的相关文章

HDU 1074 Doing Homework (状态压缩DP)

Doing Homework Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 3595    Accepted Submission(s): 1424 Problem Description Ignatius has just come back school from the 30th ACM/ICPC. Now he has a lo

HDU 1074 Doing Homework ——(状态压缩DP)

考虑到n只有15,那么状压DP即可. 题目要求说输出字典序最小的答案的顺序,又考虑到题目给出的字符串本身字典序是递增的,那么枚举i的时候倒着来即可.因为在同样完成的情况下,后选字典序大的,小的字典序就会在前面,那么整体的字典序就会更小.代码如下: 1 #include <stdio.h> 2 #include <algorithm> 3 #include <string.h> 4 #include <string> 5 #include <iostre

hdoj 1074 Doing Homework 【状态压缩dp】

题目:hdoj 1074 Doing Homework 题意:给出一些任务15个,每个任务有截至时间和需要做的天数,超期一天扣一分,求让扣分最小的安排方案. 分析:用状态压缩枚举所有的状态,dp[st]表示在st状态下的最小扣分 转移方程:dp[st | (1<<i)] = min( dp[st | ( 1 << i ) ] , dp[ st ] + 当前 i 超期的扣分 ) 注意这个题目需要打印路径,所以还要一个数组保存状态的转移,递归输出结果即可. AC 代码: #includ

HDU 1074 Doing Homework DP 状压DP

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1074 题目描述: 给你所有课程的截止时间和工作时长, 一次只能做一种作业, 问最少罚时几天 N <= 15 解题思路: 由于N很小, 所以第一反应就是状压DP, 我们可以用一个15位二进制数来表示各个课程做完还是没做完, 然后从 S 从 1 到 1 << N 枚举 i 从 1 到 N 枚举, 如果S & (1<<i) 有效则说明i 属于情况 S, 这样我们从上一步S -

HDU 1074 Doing Homework(状压DP)

Problem Description Ignatius has just come back school from the 30th ACM/ICPC. Now he has a lot of homework to do. Every teacher gives him a deadline of handing in the homework. If Ignatius hands in the homework after the deadline, the teacher will r

hdu 4352 数位dp + 状态压缩

XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2265    Accepted Submission(s): 927 Problem Description #define xhxj (Xin Hang senior sister(学姐)) If you do not know xhxj, then careful

【HDU 4352】 XHXJ&#39;s LIS (数位DP+状态压缩+LIS)

XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2422    Accepted Submission(s): 990 Problem Description #define xhxj (Xin Hang senior sister(学姐)) If you do not know xhxj, then careful

[数位dp+状态压缩] hdu 4352 XHXJ&#39;s LIS

题意: 给x.y.k,在[x,y] 范围内最长上升子序列长度是k的数有几个 思路: 模仿 LIS nlogn的想法,这里就只有10个数,进行状压 然后直接搜就好了不用二分 然后按位dp下去就ok了! 代码: #include"cstdlib" #include"cstdio" #include"cstring" #include"cmath" #include"queue" #include"al

HDU 4336 Card Collector (期望DP+状态压缩 或者 状态压缩+容斥)

题意:有N(1<=N<=20)张卡片,每包中含有这些卡片的概率,每包至多一张卡片,可能没有卡片.求需要买多少包才能拿到所以的N张卡片,求次数的期望. 析:期望DP,是很容易看出来的,然后由于得到每张卡片的状态不知道,所以用状态压缩,dp[i] 表示这个状态时,要全部收齐卡片的期望. 由于有可能是什么也没有,所以我们要特殊判断一下.然后就和剩下的就简单了. 另一个方法就是状态压缩+容斥,同样每个状态表示收集的状态,由于每张卡都是独立,所以,每个卡片的期望就是1.0/p,然后要做的就是要去重,既然

[2016-03-28][HDU][1074][Doing Homework]

时间:2016-03-28 18:46:36 星期一 题目编号:[2016-03-28][HDU][1074][Doing Homework] 题目大意:给定n门科作业的期限时间和完成耗时,每科每超过一天就扣一份,求最少扣分数 分析:n只有15,二进制枚举,状态压缩,枚举每种科目完成的状态,更新下一个状态,求最小值 #include <cstring> #include <cstdio> using namespace std; const int maxstu = 1 <&