比赛的时候想了很多……傻死了,看数据就是写状压,但是比赛完补了题发现自己好像还是算不太清楚状态压缩的时间效率,gay尬
好奇:????
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
#include<set>
#include<math.h>
#include<queue>
#include<map>
#include<stack>
#define go(i,a,b) for (int (i)=(a);(i)<=(b);(i)++)
#define ll long long
#define INF 4557430888798830399
using namespace std;
typedef pair<ll,int > pai;
struct que{
ll a,b,pre;
}c[50];
queue<pai>q;
ll dp[2100000];
bool init[2100000];
int main(){
ll n,k,ans;
while (scanf("%lld",&n)!=EOF){
go(i,1,n){
scanf("%lld%lld",&c[i].a,&c[i].b);
scanf("%lld",&k);
ll pre=0,tmp;
go(j,1,k){
scanf("%lld",&tmp);
if ((pre&(1<<tmp))==0) pre|=(1<<tmp);
}
c[i].pre=pre;
}
memset(dp,0x3f,sizeof(dp));
memset(init,false,sizeof(init));
dp[0]=0;
init[0]=true;
while (!q.empty()) q.pop();
q.push(make_pair(0,0) ); //1的当获得的价值,2的当收获的东西,3件数
ans=0;
while (!q.empty()){
pai tmp=q.front();
q.pop();
ll pre=tmp.first;
init[pre]=false;
int sum=tmp.second;
go(i,1,n){
if ((pre&(1<<i) )!=0||(pre&c[i].pre)!=c[i].pre) continue;
ll temp=(pre|(1<<i) );
if (dp[temp]==INF||dp[temp]<dp[pre]+c[i].a*(sum+1)+c[i].b){
ans=max(ans,dp[pre]+c[i].a*(sum+1)+c[i].b);
dp[temp]=dp[pre]+c[i].a*(sum+1)+c[i].b;
if (!init[temp]){
q.push(make_pair(temp,sum+1));
init[temp]=true;
}
}
}
}
printf("%lld\n",ans);
}
}
状态压缩