http://codeforces.com/gym/100676
题目大意是告诉你要修n门课,每门课有一个权值w[i], 在第k天修该课程讲获得k*w[i]的学习点数,给出了课程与先修课程的关系,要修该课程必须修完先修课程。问最多能学到多少点数。
非常简单的一道状压dp(一开始我还误导队友写成两维的去了 T^T);
dp[s] : s 的二进制存放的是已经选择的课程,在该状态下的能获得的最大的点数。
这时如果再学一门课程k,将转移到状态ss (s | (1 << k) ) ,能否转移需要判断合法性。这里把课程k的先修课程存在一个int里面,S & prev[k] == prev[k]则表示可以选项k课程。dp数组一开始需要初始化成无穷小。最后只要找dp[(1 << n ) - 1] 。
/*输入真恶心*/
#include <map> #include <cstdio> #include <vector> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int INF = 999999999; int n,m; map<string, int> Map; int w[20]; int prve[20]; void read() { cin >> n >> m;getchar(); char _a[101]; string _s, _t; int _num; int _len; for (int i=0; i<n; i++) { gets(_a); _len = strlen(_a); int k = 0; while(_a[k] < '0' || _a[k] > '9') k++; _a[k-1] = '