杭电ACM1074——Doing Homework~~状态压缩DP

原创 2015年07月28日 20:23:42

题目的意思:N门课程有作业,一个时间是最迟交的时间,一个是需要耗费多少时间来完成,到了期限,迟交多少,就扣多少分,求扣最少分的做作业的顺序。

N小于等于15,可以枚举所以的情况,数的二进制来表示各种情况。

对于集合编码成整数,可以看我的另一篇博客:点击打开链接

枚举每一门课程,S & (1 << i)表示第i门课程是否完成,为 1 就是完成了。

对于状态压缩DP还不是很熟,特别是位运算,很是蛋疼。

参考别人博客学习的。

下面的是AC的代码:

#include <iostream>
#include <cstring>
#include <string>
#include <stack>
using namespace std;

const int INF = 100000000;

struct data
{
	string name;
	int last, cost;
}Data[20];

struct DP
{
	int time, score, pre, now;//time为该状态多出来的时间,score是扣的分,pre,now用来记录路径
}dp[1 << 15 + 1];


int main()
{
	int t, n, i, end;
	cin >> t;
	while(t--)
	{
		memset(dp, 0, sizeof(dp));//初始化
		cin >> n;                 //输入
		for(i = 0; i < n; i++)
			cin >> Data[i].name >> Data[i].last >> Data[i].cost;
		end = 1 << n;
		for(int S = 1; S < end; S++)//枚举所以的状态
		{
			dp[S].score = INF;
			for(i = n - 1; i >= 0; i--)  //每一门课程
			{
				int temp = 1 << i;
				if(S & temp)             //判断第i门课程是否完成
				{ 
					int a = S - temp;    //集合S去掉 i,也就是第i门课程没完成,也就是上一个状态
					int s = dp[a].time + Data[i].cost - Data[i].last;
					if(s < 0)
						s = 0;
					if(s + dp[a].score < dp[S].score)   //分数小于现在的状态
					{
						dp[S].score = s + dp[a].score;
						dp[S].pre = a;                   //记录路径
						dp[S].now = i;                   //记录路径
						dp[S].time = dp[a].time + Data[i].cost;
					}
				}
			}
		}
		stack <int>Stack;
		cout << dp[end - 1].score << endl;
		int res = end - 1;
		while(res)          //取路径
		{
			Stack.push(dp[res].now);
			res = dp[res].pre;
		}
		while(!Stack.empty())  //输出
		{
			cout << Data[Stack.top()].name << endl;
			Stack.pop();
		}
	}
	return 0;
}



版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

DP系列之二进制状态压缩--杭电1074

状态压缩的意图是用每一位二进制表示一个状态,0表示选中状态,1表示不选状态,如果有N个物体,从中选择若干个物体,那么最终选中的状态可以用一个N位的二进制位来表示 比如 若选择了第1个物体和第3个物...

HDU1074——Doing Homework(状态压缩dp)

Doing Homework Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

状态压缩dp-HDU1074-Doing Homework

题目:    每门课的作业有截止日期和完成作业所需要的日期, 然后有多门课,如果每门课没完成会有一个惩罚,惩罚为多出来的时间。 求做作业的顺序,使得惩罚最小。 有T组数据, 每组数据 给出N门课,每门...

hdu1074 Doing Homework (状态压缩dp)

本题数据范围较小,但暴力枚举的话肯定超时,因为最坏情况将要枚举15!种情况,因此只有采取dp。 本题有点类似于经典的数塔模型,此处用已完成的课程表示当前的状态,对于某门课程,0表示还未完成,1表示已...

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

题意  有n个作业要做   给你每个作业的最后期限  和做完这个作业需要的时间  作业每超过最后期限一天就会扣一分  只能把一个作业做完了再做另一个作业  问做完所有作业至少扣多少分 作业最多只有1...
  • acvay
  • acvay
  • 2015年08月28日 14:47
  • 1047

HDU 1074 Doing Homework,dfs+剪枝(280ms),状态压缩+dp(15ms)

题意:有 n 门功课,给出完成每门功课所要的天数和要交作业的日期,超期一天不交扣一分,问怎样安排做作业的顺序可以扣分最少,把最少分输出以及做功课的顺序,如果多个顺序都可以得到最优解,输出字典序最小的那...

状态压缩DP-HDU-1074-Doing Homework

Doing HomeworkTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) T...

HDU1074Doing Homework 状态压缩DP入门

#include #include #include #include #include #include #include #include using namespace std; int n...

hdoj 1074 Doing Homework 【状态压缩dp】

题目:hdoj 1074 Doing Homework  题意:给出一些任务15个,每个任务有截至时间和需要做的天数,超期一天扣一分,求让扣分最小的安排方案。 分析:用状态压缩枚举...

HDU 1074 Doing Homework DP 状态压缩

题意:有N(N
  • NMfloat
  • NMfloat
  • 2015年12月13日 20:02
  • 150
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:杭电ACM1074——Doing Homework~~状态压缩DP
举报原因:
原因补充:

(最多只允许输入30个字)