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. delphi 2010 启动卡死,过一段时间后出现“displayNotification:堆栈溢出 怎么解决?

    解决方法:打开IE,在Internet选项中,删除历史记录.

  2. mysqlerror2003错误原因以及解决方案

    出现mysql #2003错误有一下几种原因 一.mysql数据库没有启动 这种情况也正是我遇到的,到windows服务选项里查看发现没有mysql数据库服务这个选项,记得刚开始安装mysql的时候是 ...

  3. B. Spider Man

    time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standa ...

  4. UVa 1611 Crane (构造+贪心)

    题意:给定一个序列,让你经过不超过9的6次方次操作,变成一个有序的,操作只有在一个连续区间,交换前一半和后一半. 析:这是一个构造题,我们可以对第 i 个位置找 i 在哪,假设 i  在pos 位置, ...

  5. 2019年5月22日 AY 程序员调侃语录

    我是AY,杨洋,做wpf开发的,最近得了一种病,程序员患得患失综合征.同事说,我年纪在变大,技术跟不上.业余之间,我原创了写了一些语录,给大家中午休息,累疲惫的时候,开心放松下. 1.活着的每一天都无 ...

  6. c语言基本数据类型相关

    1byte = 8bit  数据类型  比特长度  位长度  IO表达  int  2/4  16/32  %d   unsigned (int)  2/4  16/32  %u  short int ...

  7. Android Studio:layout-sw600dp文件夹中创建activity_main.xml

    1.右键res文件夹,新建Android resource directory文件夹 2.在resource type中选择layout  3.将Directory name命名为layout-sw6 ...

  8. TP3.2单字母函数

    A方法 A方法用于在内部实例化控制器 调用格式:A(‘[项目://][分组/]模块’,’控制器层名称’) 最简单的用法: $User = A('User'); 表示实例化当前项目的UserAction ...

  9. POJ1700 【经典过河问题,贪心】

    题意: n个人过河, 船每次只能坐两个人, 然后船载每个人过河的所需时间不同, 问最快的过河时间. 思路: 仅仅启发一下思维: 我相信很多人一下子的想法就会有,每次最快和那些慢的过去,然后让最快一直来 ...

  10. Jquery+ajaxfileupload上传文件

    1.说明 ajaxfileupload.js是一款jQuery插件,用于通过ajax上传文件. 下载地址:http://files.cnblogs.com/files/lengzhan/ajaxfil ...