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 | ...
随机推荐
- Python mutilprocess模块之第二种创建进程方法--继承Process类
'''创建新的进程的第二种方法: 使用类的方式,可以自己定义一个类,继承Process类,每次实例化这个类的时候, 就等于实例化一个进程对象 '''from multiprocessing impor ...
- Memcached使用总结之:使用Python操作memcache
Python连接memcached的库有很多,处于简单以及高效的原则,最终选择了pymemcache,优点完全实现了memcached text协议对于send/recv操作可以配置timeout支持 ...
- margin-----总结----解析逻辑
margin的解析逻辑 在 margin 中 top.right.bottom.left 的参考线并不一致为一类,而是分为了两类参考线,top 和 left 的参考线属于一类,right 和botto ...
- Ruby 类的创建
class Language def initialize(name, creator) @name = name @creator = creator end def description pu ...
- View Controller Programming Guide for iOS---(八)---Using View Controllers in the Responder Chain
Using View Controllers in the Responder Chain 响应链中使用视图控制器 View controllers are descendants of the UI ...
- FTP相关内容
FTP相关介绍 FTP 1)File Transfer Protocol ( FTP ) 是相当古老的网络协议之一,他最主要的功能就是进行 Server端与 Client 端之间的档案传送的功能.这个 ...
- POJ1276【多重背包】
题意: 给出一个价值sum,然后给出n,代表n个方案,接着n对代表个数与价值,要求最接近sum,但不超过sum的价值. 思路: 多重背包,利用二进制拆分达到保证对于0..n间的每一个整数,均可以用若干 ...
- Untiy检测各类设备输入
轴需要单独设置 using UnityEngine; using System.Collections; using UnityEngine.UI; public class OutputKey : ...
- P5024 保卫王国
传送门 我现在还是不明白为什么NOIPd2t3会是一道动态dp-- 首先关于动态dp可以看这里 然后这里就是把把矩阵给改一改,改成这个形式\[\left[dp_{i-1,0},dp_{i-1,1}\r ...
- C#语言开发规范-ching版
拙劣之处请大家斧正,愚某虚心接受,如有雷同,不胜荣幸 C#语言开发规范 作者ching 1. 命名规范 a) 类 [规则1-1]使用Pascal规则命名类名,即首字母要大写. eg: Class T ...