状态压缩DP Doing Homework

Posted Vincent_0000

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了状态压缩DP Doing Homework相关的知识,希望对你有一定的参考价值。

题目提交点

点我进入oj提交题目

题目分析 + 自我总结

  • 题意大意

给作业做的时间排序,使得扣除的分数最小,并输出方案。

  • 分析题型

我考虑的是01背包,后面发现01背包无法实现都选择的情况,前后都冲突了,导致这个题目没有做出来。

对于正确思考这个题目,应该这么去做:
查看数据范围,n很小,可以直接排除背包问题,像这种题目,显然不会出数据范围这么小的背包问题。
遇到这种时候就要先想想暴力怎么写。

我们使用DFS, 每次都遍历之前没有遍历过的点,保存当前所扣除的分数,该分数等于,之前所以走过所扣除的分数加上现在的分数,现在的分数等于已经走过路径所花费的时间+做完这个作业需要的时间 - 时间期限。
遍历完所有的点之后更新答案和路径。

这种写法显然会超时,而且是求最优的题目, 这种数据范围之内有没有可以相似的DP类型呢?
有,状态压缩DP。
所以尝试使用状态DP做这个题目,初步判断为状态压缩DP + 记录路径。

  • DP优化
for (遍历所有情况)
	对最后一个状态和前面一群状态进行分析(DP基本想法)
		for(选择哪一个作业作为我们当前情况的最后一种情况) (逆序)
			状态转移方程 f(当前情况) = min(f(当前情况), f(之前的分数) + 现在的分数)

第二个for循环需要逆序的原因是我们遍历结果是从后往前的,而题目给的字典序是从前往后排是依次增大的,与我们的路径相矛盾。

  • 目标

f(全都选好的情况)

AC代码

#include<bits/stdc++.h> 
using namespace std;

#define _for(i, a, b) for (int i = (a); i < (b); ++i) 
#define _rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define For(i, a, b) for (int i = (a); i >= (b); --i)
#define debug(a) cout << #a << " = " << a << ENDL
#define ENDL "\\n"
#define x first 
#define y second 
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;

const int N = 15 + 5, M = (1 << 15) + 5, INF = 0x3f3f3f3f;
int f[M], D[N], C[N],v[M], last[M];
char s[N][105];

void print(int x) {
	if (!x) return;
	print(x - (1 << last[x]));
	cout << s[last[x]] << ENDL;
}

int main() {
#ifdef LOCAL
	freopen("data.in", "r", stdin);
#endif
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);

	int T;
	cin >> T;
	while (T--) {
		int n;
		cin >> n;
		_for(i, 0, n) cin >> s[i] >> D[i] >> C[i];

		int sz = 1 << n;
		_for(i, 1, sz) {
			f[i] = INF;
			For(j, n - 1, 0) {
				int k = 1 << j;
				if (!(i & k)) continue;
				int w = v[i - k] + C[j] - D[j];
				if (w < 0) w = 0;
				if (f[i] > f[i - k] + w) {
					f[i] = f[i - k] + w;
					v[i] = v[i - k] + C[j];
					last[i] = j;
				}
			}
		}

		cout << f[sz - 1] << ENDL;
		print(sz - 1);
	}

	return 0;
} 

以上是关于状态压缩DP Doing Homework的主要内容,如果未能解决你的问题,请参考以下文章

状态压缩DP,附上例题(HDU - 1074 Doing Homework )

状态压缩DP Doing Homework

HDU 1074 Doing Homework 状态压缩DP

Doing Homework_状态压缩

Doing Homework HDU - 1074 状态压缩

Doing Homework---hdu1074(状态压缩&&记忆化搜索)