G. Training Camp
[ Color: Yellow ]
Montaser is planning to train very hard for ACM JCPC 2015; he has prepared a list with n topics
to study in the next n days, one topic every day.
Montaser knows that some topics depend on other topics, so he asked coach Fegla and got a list
of m constraints on the order in which he should study these topics.
Also, coach Fegla told him that when he studies topic x on the kth day (1 ≤ k ≤ n), his level will
increase by k*Wx, where Wx is a weight for topic x, representing how hard it is.
Given the list of topics, the weight of each topic, and the list of constrains, can you tell Montaser
what is the maximum level he can reach in these n days? He is currently at level 0 L.

Input
The first line of input contains one integer T representing the number of test cases (1 ≤ T ≤ 128).
The first line of each test case contains two integers: n and m (1 ≤ n ≤ 18).
The next n lines, each contains the title of one of the topics followed by a space, then an integer
W that represents the weight of this topic (1 ≤ W ≤ 100).
The next m lines are of the form: Topic 1 --> Topic 2, which means that Topic 1 must be studied
before Topic 2.
Titles contain only English letters and spaces (no more than 40 characters).
Test cases are separated by a blank line.

Output
For each test case, print the maximum level that Montaser can reach.

Sample Input 
1
3 2
Implementation 3
Dynamic Programming 10
Greedy 7
Greedy --> Dynamic Programming
Implementation --> Dynamic
Programming

Sample Output
47

题意:

  就是一个人要在n天学完n门课程,每天学习一门,在第i天学习第w[i]门课程他的姿势水平会增加i * w[i],然后这些课程有先后顺序,类似于拓扑排序的

顺序,比如:a -> b, c -> b, c -> a就表示学习a之前要先学习c,学习b之前要先学习a和c,求他能达到的最高的姿势水平。

思路:

  输入比较烦人,考虑到n只有18,很容易想到状态压缩,用dp[i]表示状态为i的时候能达到的最高姿势水平,那么dp[i]的值就可以通过枚举状态i的为1的位来得到当前的值

比如dp[010011(2)] = max(dp[000011(2)] + 3(day) * w[4], dp[010001(2) + 3(day) * w[1], dp[010010(2)] + 3(day) * w[0])来得到。复杂度为

T*n*logn但是T比较大 满状态的话复杂度是128*18*2^18 = 6e8,很容易被卡常。所以做个优化,就是因为不是没个状态都是可以的,因为要按照拓扑排序的

顺序,所以我们在转移方程的时候把能够存在的状态给标记一下,这样就有很多状态不是o(n)而是o(1)了。

代码:

/** @xigua */
#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<cstring>
#include<queue>
#include<set>
#include<string>
#include<map>
#include<climits>
#define PI acos(-1)
using namespace std;
typedef long long ll;
typedef double db;
const int maxn = 1e2 + 5;
const int mod = 1e9 + 7;
const int INF = 1e8 + 5;
const ll inf = 1e15 + 5;
const db eps = 1e-9;
int w[maxn], dp[1<<20];
map<string, int> mp;
int n, m, pre[25]; void solve() {
mp.clear();
cin >> n >> m; cin.get();
for (int k = 0; k < n; k++) {
string s, name; int xx = 0;
getline(cin, s); int flag = 1;
for (int i = 0; i < s.size(); i++) {
if (flag && s[i+1] >= '0' && s[i+1] <= '9') {
flag = 0; continue;
}
if (flag) name += s[i];
if (!flag) xx = xx * 10 + s[i] - '0';
}
mp[name] = k; w[k] = xx;
}
memset(pre, 0, sizeof(pre));
for (int i = 1; i <= m; i++) {
string s, xx, hh;
getline(cin, s); int flag = 0;
for (int j = 0; j < s.size(); j++) {
if (s[j+1] == '-') {
flag = 1; continue;
}
if (flag == 1 && s[j] == ' ') {
flag = 2; continue;
}
if (flag == 0) xx += s[j];
if (flag == 2) hh += s[j];
}
pre[mp[hh]] |= (1 << mp[xx]); //如果要学习第mp[hh]课程的话要先学习mp[xx]课程
}
for (int i = 1; i < (1 << n); i++)
dp[i] = -INF;
dp[0] = 0;
bool can[1<<19] = {0}; can[0] = 1;
for (int i = 0; i < (1 << n); i++) {
if (!can[i]) continue; //不存在当前状态就跳过
int num = 0;
for (int j = 0; j < n; j++) {
num += ((i >> j) & 1);
}
for (int j = 0; j < n; j++) {
int xx = i | (1<<j);
if (xx != i) {
if ((i & pre[j]) != pre[j]) continue; //状态i中是否包括了要学习课程j的所以课程
can[xx] = true;
dp[xx] = max(dp[xx], dp[i] + (num+1) * w[j]);
}
}
}
cout << dp[(1<<n) - 1] << endl;
} int main() {
//cin.sync_with_stdio(false);
//freopen("isharp.in", "r", stdin);
//freopen("isharp.out", "w", stdout);
int t = 1; cin >> t; while (t--) {
solve();
}
return 0;
}
/*
1
3 2
Implementation 3
Dynamic Programming 10
Greedy 7
Greedy --> Dynamic Programming
Implementation --> Dynamic Programming
*/

  

Gym - 100676G Training Camp (状压dp)的更多相关文章

  1. 状压dp Gym - 100676G

    http://codeforces.com/gym/100676 题目大意: 给你n个科目,m个关系,例如A->B,表示要学习B科目,一定要把A科目学习掉.同理,如果还有C->B,那么,B ...

  2. Codeforces Gym 100015F Fighting for Triangles 状压DP

    Fighting for Triangles 题目连接: http://codeforces.com/gym/100015/attachments Description Andy and Ralph ...

  3. Codeforces Gym 100610 Problem K. Kitchen Robot 状压DP

    Problem K. Kitchen Robot Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/10061 ...

  4. 2014 Super Training #1 B Fix 状压DP

    原题: HDU 3362 http://acm.hdu.edu.cn/showproblem.php?pid=3362 开始准备贪心搞,结果发现太难了,一直都没做出来.后来才知道要用状压DP. 题意: ...

  5. CCPC-Wannafly Winter Camp Day3 Div1 - 精简改良 - [生成树][状压DP]

    题目链接:https://zhixincode.com/contest/14/problem/D?problem_id=206 样例输入 1  5 5 1 2 1 1 3 1 2 4 1 2 5 1 ...

  6. 【CCPC-Wannafly Winter Camp Day3 (Div1) D】精简改良(状压DP)

    点此看题面 大致题意: 给你一张图,定义\(dis(i,j)\)为\(i\)与\(j\)的最短距离,现要求删去若干条边,使得图仍然联通,且\(\sum_{i=1}^n\sum_{j=i+1}^ndis ...

  7. codeforces Diagrams & Tableaux1 (状压DP)

    http://codeforces.com/gym/100405 D题 题在pdf里 codeforces.com/gym/100405/attachments/download/2331/20132 ...

  8. HDUOJ Clear All of Them I 状压DP

    Clear All of Them I Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 122768/62768 K (Java/Oth ...

  9. 暑假集训 || 状压DP

    emm 位操作实现技巧: 获得第i位的数据:  if(!(data & (1<< i)))  则data的第 i 位为0,else 为 1 设置第i位为1,data=(data | ...

随机推荐

  1. POJ3020 二分图匹配——最小路径覆盖

    Description The Global Aerial Research Centre has been allotted the task of building the fifth gener ...

  2. 【JSOI 2014】序列维护

    [题目链接] 点击打开链接 [算法] 线段树 注意标记下传 [代码] #include<bits/stdc++.h> using namespace std; #define MAXN 5 ...

  3. 嵌入式Linux学习方法——给那些彷徨者(下)

    上一章解决了嵌入式Linux的“学什么”问题,这一章则具体来说一下“怎么学”. 只要做好以下3点: 1.学习顺序.学习任何东西都应该由浅入深,不能一口吃下一个大胖子,得循序渐进.很多刚开始想学习Lin ...

  4. bzoj1097

    最短路+状压dp 肯定是状压dp 那么我们把k个点的单源最短路预处理出来,然后dp[i][j]表示状态为i,当前在j需要走的最短距离,给定的限制用状态压一下就行了 注意特判k=0的情况 #includ ...

  5. HDU - 2828 网络流

    题目大意 有n个灯,m个开关,由于线路乱接导致可能有多个开关对应一个灯(并联),有的灯在开关开的时候亮 有的灯在开关关的时候亮,[每个开关最多对应两盏灯],试找出一种开关的ON,OFF状态,使得所有灯 ...

  6. 014--python运算符和作业改进

    一.运算符 % 取模,返回商的余数 10/3     3.33333333335 10//3    3   地板除,取整数,不是四舍五入 a = 3  b = 5  ----->   a< ...

  7. ASP.NET Core MVC 2.x 全面教程_ASP.NET Core MVC 21. Model 验证 Again

    深入的将Model验证 手动添加验证的错误 view里面显示每个属性的验证错误信息 显示整个model级别错误 自定义验证 如果业务逻辑需要比较复杂的验证.而且这个验证逻辑可能到处复用的话就应该考虑使 ...

  8. POJ1236【图的前连通(缩点)】

    题意: 1.初始至少需要向多少个学校发放软件,使得网络内所有的学校最终都能得到软件. 2.至少需要添加几条传输线路(边),使任意向一个学校发放软件后,经过若干次传送,网络内所有的学校最终都能得到软件. ...

  9. python 迭代器 Iterator

    一.可迭代对象定义 可以直接作用于for循环的数据类型有以下几种: 一类是集合数据类型,如list.tuple.dict.set.str.bytes.bytearray等: 一类是generator, ...

  10. noip 2012 Day2 T2 借教室

    一.暴力简述 甩链接.jpeg 首先我们不难看出,这道题————并不是一道多难的题,因为显然,第一眼看题目时便很容易地想到暴力如何打:枚举每一种订单,然后针对每一种订单,对区间内的每一天进行修改(做减 ...