1. 程式人生 > >2018南京網路賽 E.AC Challenge 狀壓dp

2018南京網路賽 E.AC Challenge 狀壓dp

 

  • 1000ms
  • 128536K

AC Challenge

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 南京賽區網路預賽

題意:給你n個作業,每完成一個作業的可以得到a*t+b的獎勵,t表示完成的第幾個作業,要完成第i個作業必須完成其他若干個作業,最後問你最後能得到的最大的獎勵。

思路:毫不猶豫狀壓dp,dp[j]表示當前狀態下可以得到的最大獎勵,j中二進位制中的01表示那個左右有沒有被完成,

我的狀態轉移方程為

if((sta[i]&j)==sta[i]&&(j!=(j|(1<<(i-1)))))dp[j|(1<<(i-1))]=max(dp[j|(1<<(i-1))],dp[j]+get1(j|(1<<(i-1)))*a[i]+b[i]);

表示在狀態j的時候,完成第i個作業需要的狀態為sta[i],當狀態j滿足狀態sta[i]且狀態j下第i個作業還沒有被完成下進行轉移,

get1()表示這個數的二進位制中有多少個1,應為每個1表示那個作業完成了。

程式碼:

#include<stdio.h>
#include<string.h>
#include<cmath>
#include<stdlib.h>
#include<time.h>
#include<algorithm>
#include<iostream>
#include<vector>
#include<queue>
#include<set>
#include<map>
#define ll long long
#define qq printf("QAQ\n");
using namespace std;
const int maxn=5+(1<<21);
const int inf=0x3f3f3f3f;
const ll linf=8e18+9e17;
const int mod=1e9+7;
const double e=exp(1.0);
const double pi=acos(-1);
const double eps=1e-6;
int sta[maxn];
ll dp[maxn]={0};
int get1(int x)
{
	int ans=0;
	while(x)
	{
		if(x&1)ans++;
		x/=2;
	}
	return ans;
}
int main()
{
	int t,n,last;
	ll a[25],b[25];
	while(scanf("%d",&n)!=EOF)
	{
		for(int i=1;i<=n;i++)
		{
			scanf("%lld%lld%d",&a[i],&b[i],&t);
			sta[i]=0;
			for(int j=1;j<=t;j++)
			{
				scanf("%d",&last);
				sta[i]|=1<<(last-1);
			}
		}
		memset(dp,-inf,sizeof dp);
		dp[0]=0;
		ll ans=0;
		for(int j=0;j<=1<<n;j++)//列舉狀態 
		for(int i=1;i<=n;i++)//列舉作業 
		{
			if((sta[i]&j)==sta[i]&&(j!=(j|(1<<(i-1))))){
			//狀態滿足   			當前狀態第i個作業沒完成 
				dp[j|(1<<(i-1))]=max(dp[j|(1<<(i-1))],dp[j]+get1(j|(1<<(i-1)))*a[i]+b[i]);
			}
		}
		int mx=(1<<n);
		for(int i=0;i<=mx;i++)
		ans=max(ans,(ll)dp[i]);
		printf("%lld\n",ans);
	}
	return 0;
}