Gym - 100676G Training Camp (状压dp)
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)的更多相关文章
- 状压dp Gym - 100676G
http://codeforces.com/gym/100676 题目大意: 给你n个科目,m个关系,例如A->B,表示要学习B科目,一定要把A科目学习掉.同理,如果还有C->B,那么,B ...
- Codeforces Gym 100015F Fighting for Triangles 状压DP
Fighting for Triangles 题目连接: http://codeforces.com/gym/100015/attachments Description Andy and Ralph ...
- 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 ...
- 2014 Super Training #1 B Fix 状压DP
原题: HDU 3362 http://acm.hdu.edu.cn/showproblem.php?pid=3362 开始准备贪心搞,结果发现太难了,一直都没做出来.后来才知道要用状压DP. 题意: ...
- 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 ...
- 【CCPC-Wannafly Winter Camp Day3 (Div1) D】精简改良(状压DP)
点此看题面 大致题意: 给你一张图,定义\(dis(i,j)\)为\(i\)与\(j\)的最短距离,现要求删去若干条边,使得图仍然联通,且\(\sum_{i=1}^n\sum_{j=i+1}^ndis ...
- codeforces Diagrams & Tableaux1 (状压DP)
http://codeforces.com/gym/100405 D题 题在pdf里 codeforces.com/gym/100405/attachments/download/2331/20132 ...
- 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 ...
- 暑假集训 || 状压DP
emm 位操作实现技巧: 获得第i位的数据: if(!(data & (1<< i))) 则data的第 i 位为0,else 为 1 设置第i位为1,data=(data | ...
随机推荐
- java -- 虚拟机和内存
从大方向来分:栈内存,堆内存,方法区,本地方法栈,程序计数器 java从存储数据的角度来分: 寄存器(register):最快的存储区,由编译器根据需求进行分配,不由认为控制. 堆栈(statck): ...
- CoreGpaphics
CoreGpaphics基本应用 CGAffineTransformMake开头的函数 是基于最初始的位置来变化的 带有CGAffineTransform参数是基于CGAffineTransform的 ...
- margin-负值
总结:margin负值的影响: 当元素(块级元素)没有设置宽度时:margin负值会增加元素的宽度,当设置宽度时,margin负值只会影响元素的位置. 就是负的边距好像能减小元素在文档流中的尺寸一样, ...
- bzoj4556
后缀自动机+二分+倍增+线段树合并 后缀自动机真好用 后面一个串是固定的,那么我们要对前面的串进行一些操作.我们想既然是求lcp,那么我们得先翻转原串,这样前缀变成了后缀,然后二分一下,从d在自动机上 ...
- 【旧文章搬运】扩展一下ProcessNotify~~
原文发表于百度空间,2009-01-08 看雪论坛地址:https://bbs.pediy.com/thread-80109.htm DebugMan论坛地址:http://www.debugman. ...
- windows上搭建php环境
在Windows 7下进行PHP环境搭建,首先需要下载PHP代码包和Apache与Mysql的安装软件包. PHP版本:php-5.3.2-Win32-VC6-x86,VC9是专门为IIS定制的,VC ...
- HDU 1230饭前开胃菜
题意不讲了.. 没思路,上去就是干.... 两个所谓要加的数直接存到数组,开一个标记的数组,然后直接加,乱搞一波,就好了. 细心一点. #include<iostream> #includ ...
- bzoj 1082: [SCOI2005]栅栏【二分+dfs】
二分答案,dfs判断是否可行,当b[k]==b[k-1]时可以剪枝也就是后移枚举位置 #include<iostream> #include<cstdio> #include& ...
- PJzhang:工作之余一起来看剧
猫宁!!! 最近几个月陆续看了4部电视剧,不错,分别来自4个国家或地区,英国.日本.中国香港.俄罗斯,是的,没有美剧,平时真的很少看美剧. 1-IT狂人,英剧,一共4季,每季6集,每集25分钟左右. ...
- git部分指令
git stash #会把所有未提交的修改(包括暂存的和非暂存的)都保存起来,用于后续恢复当前工作目录 git stach pop #恢复之前缓存的工作目录 切换分支: git checkout de ...