Dlsj is competing in a contest with n(0<n≤20)n (0 < n \le 20)n(0<n≤20) problems. And he knows the answer of all of these problems.
However, he can submit iii-th problem if and only if he has submitted (and passed, of course) sis_isi? problems, the pi,1p_{i, 1}pi,1?-th, pi,2p_{i, 2}pi,2?-th, ........., pi,sip_{i, s_i}pi,si??-th problem before.(0<pi,j≤n,0<j≤si,0<i≤n)(0 < p_{i, j} \le n,0 < j \le s_i,0 < i \le n)(0<pi,j?≤n,0<j≤si?,0<i≤n) After the submit of a problem, he has to wait for one minute, or cooling down time to submit another problem. As soon as the cooling down phase ended, he will submit his solution (and get "Accepted" of course) for the next problem he selected to solve or he will say that the contest is too easy and leave the arena.
"I wonder if I can leave the contest arena when the problems are too easy for me."
"No problem."
—— CCF NOI Problem set
If he submits and passes the iii-th problem on ttt-th minute(or the ttt-th problem he solve is problem iii), he can get t×ai+bit \times a_i + b_it×ai?+bi? points. (∣ai∣,∣bi∣≤109)(|a_i|, |b_i| \le 10^9)(∣ai?∣,∣bi?∣≤109).
Your task is to calculate the maximum number of points he can get in the contest.
Input
The first line of input contains an integer, nnn, which is the number of problems.
Then follows nnn lines, the iii-th line contains si+3s_i + 3si?+3 integers, ai,bi,si,p1,p2,...,psia_i,b_i,s_i,p_1,p_2,...,p_{s_i}ai?,bi?,si?,p1?,p2?,...,psi??as described in the description above.
Output
Output one line with one integer, the maximum number of points he can get in the contest.
Hint
In the first sample.
On the first minute, Dlsj submitted the first problem, and get 1×5+6=111 \times 5 + 6 = 111×5+6=11 points.
On the second minute, Dlsj submitted the second problem, and get 2×4+5=132 \times 4 + 5 = 132×4+5=13 points.
On the third minute, Dlsj submitted the third problem, and get 3×3+4=133 \times 3 + 4 = 133×3+4=13 points.
On the forth minute, Dlsj submitted the forth problem, and get 4×2+3=114 \times 2 + 3 = 114×2+3=11 points.
On the fifth minute, Dlsj submitted the fifth problem, and get 5×1+2=75 \times 1 + 2 = 75×1+2=7 points.
So he can get 11+13+13+11+7=5511+13+13+11+7=5511+13+13+11+7=55 points in total.
In the second sample, you should note that he doesn't have to solve all the problems.
样例输入1复制
5 5 6 0 4 5 1 1 3 4 1 2 2 3 1 3 1 2 1 4
样例输出1复制
55
样例输入2复制
1 -100 0 0
样例输出2复制
0
题目来源
ACM-ICPC 2018 南京赛区网络预赛
代码高亮 Sublime Vim Emacs
环境配色亮色配色暗色配色 暗色配色
返回
- 亮色配色
- 暗色配色
代码缩进248 4
返回
- 2
- 4
- 8
C 语言C++ 语言 (C++11)Java 语言 C++ 语言 (C++11)
返回
- C 语言
- C++ 语言 (C++11)
- Java 语言
- main.cpp
通用
逻辑
循环
数学
文本
列表
颜色
变量
函数
69
if((has&sta[i])==sta[i]) dfs(has|(1<<i),t+1,v+1LL*a[i]*t+1LL*b[i]);///满足前提的情况下
49
}
50
?
51
///for(int i=0;i<n;i++) cout<<sta[i]<<endl;
52
?
53
memset(dp,-1,sizeof(dp));
54
ans=0;
55
dfs(0,1,0);
56
for(int i=0;i<(1<<n);i++) ans=max(ans,dp[i]);
57
printf("%lld\n",ans);
58
?
59
return 0;
60
}
61
/*
62
5
63
5 6 0
64
4 5 1 1
65
3 4 1 2
66
2 3 1 3
67
1 2 1 4
68
*/
69
?
关闭终端 终端 - 计蒜客
只看题面
#pragma comment(linker, "/STACK:102400000,102400000")
#include<bits/stdc++.h>
using namespace std;
#define debug puts("YES");
#define rep(x,y,z) for(int (x)=(y);(x)<(z);(x)++)
#define lrt int l,int r,int rt
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define ll long long
const int maxn =3e3+5;
const int mod=1e9+7;
ll gcd(ll x,ll y){return y==0?x:gcd(y,x%y);}
ll powmod(ll x,ll y){ll t;for(t=1;y;y>>=1,x=x*x%mod) if(y&1) t=t*x%mod;return t;}
/*
题目大意:做题目,
一个拓扑图,每道题目的权重根据做到当前题目的时间而定,
求最优权重。一看数据量状压没跑了。状压+搜索敲定,本人比赛时由于好久没刷这类型题目了,
居然TMD多想了个状态,就是可达领域的状态,,,天呐,,不是说好的DFS大暴力的嘛。
虽然不影响但是浪费了超多时间。这道题思维清楚的话可以秒,代码一点也不难。
就是有些小思维点,想清楚就行了。
首先DFS中记录了当前的状态,就是已经走过的点,
然后下面延扩要探索到能走到的点,
判断条件是用位运算代替。
最后用dp数组剪下枝即可。
因为同一个状态数的话,总时间是一样的,产生的权重不同是
因为选择顺序的不同。这样判定数组就可以有效的剪枝。
利用状态压缩暴力枚举就行了。
*/
///数据域
int n,q,x;
int a[24],b[24];
int sta[24];
///dp与答案
ll dp[1<<21];///状态最优方案
ll ans=0;
void dfs(int has,int t,ll v)
{if(dp[has]<v||dp[has]==-1) dp[has]=v;else return ;for(int i=0;i<n;i++){if(has&(1<<i)) continue;///如果已经走过没必要再走if((has&sta[i])==sta[i])dfs(has|(1<<i),t+1,v+1LL*a[i]*t+1LL*b[i]);///满足前提的情况下}
}int main()
{scanf("%d",&n);for(int i=0;i<n;i++){scanf("%d%d",&a[i],&b[i]);scanf("%d",&q);for(int j=0;j<q;j++){scanf("%d",&x);x--;sta[i]+=(1<<x);///到达i的条件}}memset(dp,-1,sizeof(dp));ans=0;dfs(0,1,0);for(int i=0;i<(1<<n);i++) ans=max(ans,dp[i]);printf("%lld\n",ans);return 0;
}
/*
5
5 6 0
4 5 1 1
3 4 1 2
2 3 1 3
1 2 1 4
*/