A very good report count solving problem-solving Report: Dynamic Programming: Courses large operations

This question should be grateful I was not so I learned to shoot?
Sign is the use of input and output redirection file to get inside, the specific code is two lines:

	freopen("hwin.txt", "r", stdin);
	freopen("hwoutstd.txt", "w", stdout);

Lexicographical really sinkhole ...... but that mistake really mentally to explode ......

topic:

Description
Xiaoming School of Peking University third-year undergraduate students. He likes to participate in a variety of campus community. This semester coming to an end, the deadline for each course the big job is coming, but Xiao Ming has not yet started. Each course has a big job courses, each course has a big job deadline. If the deadline for submission of more than X days, then he will be deducted X points. For each large operations, Xiao Ming to spend a day or several days to complete. He can not do multiple simultaneous large operations, he only finished with the current project before they can start a new project. Steve wants you to help him map out the best way (to complete a large job order) to reduce the penalty points.

Input
Input consists of several test samples.
The first input line is a positive integer T, representing the number of test samples.
For each test sample, the behavior of a first positive integer N (1 <= N <= 15) represents the number of courses.
Next N rows, each row containing a string S (no more than 50 characters) represents the course name and two integers D (time off work Congress) and C (the large job completion time required).
Note that the order of all of the programs are arranged in the input appears in lexicographic order.
Output
For each test case, output a minimum order of the corresponding points and the completion of the course.
If there are more optimal solution, please output lexicographically front of the program.
Sample input
2
. 3
Computer. 3. 3
Dictionary Dictionary English. 1 20 is
the Math. 3 2
. 3
Computer. 3. 3
Dictionary Dictionary English. 6. 3
the Math. 6. 3
sample output
2
Computer
the Math
Dictionary Dictionary English
. 3
Computer
Dictionary Dictionary English
the Math
prompts
the second test sample, the course completion order Computer-> English -> Math and Computer-> Math-> English will result in 3 penalty points, but we choose the former, because the front in the dictionary preface.
Shaped pressure DP, TSP variants. If you do not speak really sets TSP model really can not think of ...... beginning to think of the state transition equation:
dp [S] = dp [SJ] + c (j)
where c (j) is to do after the finish sj j buckle score.
Then would not, I did not think like I do not know how the pressure cycle (Implying 15 * 15? Almost made enumeration) finally saw the idea handout.
AC code is as follows:

#include <iostream>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;
struct info {
	string name;
	int ddl;
	int t;
};
struct node {
	int pre;
	int thisone;
	int act; //all time consumed
	int minscore;
	node() {
		pre = 0;
		thisone = 100;
		act = 0;
		minscore = 0xffffff;
	}
};
int main() {
	int T;
	cin >> T;
	while (T--) {
		node dp[(1 << 15) + 1];
		info hw[15];
		int num;
		cin >> num;
		for (int i = 0; i < num; ++i) {
			cin >> hw[i].name >> hw[i].ddl >> hw[i].t;
			//dp[(1 << i)].act = hw[i].t;
			//dp[(1 << i)].minscore = max(hw[i].t - hw[i].ddl, 0);
			//dp[(1 << i)].thisone = i;
		}
		dp[0].minscore = 0;
		int all = pow(2, num);
		for (int i = 1; i < all; ++i) {
			for (int j = 0; j < num; ++j) {
				if ((i >> j) & 1) {
					if (dp[i].minscore > dp[i & (~(1 << j))].minscore + max(dp[i & (~(1 << j))].act + hw[j].t - hw[j].ddl, 0)) {
						dp[i].pre = (i & (~(1 << j)));
						dp[i].minscore = dp[dp[i].pre].minscore + max(dp[dp[i].pre].act + hw[j].t - hw[j].ddl, 0);
						dp[i].act = dp[dp[i].pre].act + hw[j].t;
						dp[i].thisone = j;
					}
					else if (dp[i].minscore == dp[i & (~(1 << j))].minscore + max(dp[i & (~(1 << j))].act + hw[j].t - hw[j].ddl, 0)) {
						int kl = dp[i].pre, kr = (i & (~(1 << j)));
						vector <int> left;
						vector <int> right;
						left.push_back(dp[i].thisone);
						right.push_back(j);
						while (kl != 0) {
							left.push_back(dp[kl].thisone);
							right.push_back(dp[kr].thisone);
							kl = dp[kl].pre;
							kr = dp[kr].pre;
						}
						reverse(left.begin(), left.end());
						reverse(right.begin(), right.end());
						for (int k = 0; k < left.size(); ++k) {
							//一开始没加这个if
							if (right[k] > left[k]) {
								break;
							}
							if (right[k] < left[k]) {
								dp[i].pre = (i & (~(1 << j)));
								dp[i].minscore = dp[dp[i].pre].minscore + max(dp[dp[i].pre].act + hw[j].t - hw[j].ddl, 0);
								dp[i].act = dp[dp[i].pre].act + hw[j].t;
								dp[i].thisone = j;
								break;
							}
						}
					}
				}
			}
		}
		cout << dp[all - 1].minscore << endl;
		int k = all - 1;
		vector <int> output;
		while (k != 0) {
			output.push_back(dp[k].thisone);
			k = dp[k].pre;
		}
		for (int i = output.size() - 1; i >= 0; --i) {
			cout << hw[output[i]].name << endl;
		}
	}
	return 0;
}

There is, to see a link to the code is extremely clever in terms of lexicographic ordering, it is to shoot with the standard process:
https://blog.csdn.net/yhjpku/article/details/80698249

Guess you like

Origin blog.csdn.net/weixin_44288817/article/details/90554292