#include<iostream>
using namespace std;
#include<algorithm>
#include<string.h>
int n;
int a[25];
int b[25];
int limit[25];
int yilai[25];
int bin[25];
long long dp[2000005];
int total;
long long ans=-1;
void GetBin()
{
int i;
bin[0]=1;
for(i=1;i<25;i++)
bin[i]=2*bin[i-1];
}
int check1(int state)
{
int i;
int onenum=0;
for(i=0;i<n;i++)
{
if((state&bin[i])!=0)
onenum++;
}
return onenum;
}
bool check2(int state)
{
int i,j;
for(i=0;i<n;i++)
{
if((state&bin[i])!=0)//当前state下做了这道题
{
if((state&yilai[i])<yilai[i])
return false;
}
}
return true;
}
int main()
{
GetBin();
memset(yilai,0,sizeof(yilai));
memset(dp,0,sizeof(dp));
scanf("%d",&n);
total=1<<n;
int i,j,k;
for(i=0;i<n;i++)
{
scanf("%d%d",&a[i],&b[i]);
scanf("%d",&limit[i]);
//int j;
for(j=0;j<limit[i];j++)
{
int y1;
scanf("%d",&y1);
yilai[i]=yilai[i]|bin[y1-1];
}
}
for(i=1;i<=n;i++)
{
for(j=0;j<total;j++)//当前状态
{
if(check1(j)!=(i-1))//判断是否做了i-1道题目
continue;
if(check2(j)==0)//判断所做题目是否合法
continue;
for(k=0;k<n;k++)
{
if((bin[k]&j)!=0)
continue;
if((yilai[k]&j)<yilai[k])
continue;
//cout<<j<<" hh "<<k<<endl;
dp[j|bin[k]]=max(dp[j|bin[k]],dp[j]+a[k]*i+b[k]);
}
}
}
for(i=0;i<total;i++)
ans=max(ans,dp[i]);
printf("%lld\n",ans);
return 0;
}
ACM-ICPC 2018 南京赛区网络预赛-E题(状压dp)
最新推荐文章于 2020-02-07 20:55:10 发布