状压dp
因为n比较小,我们可以考虑
具体的,dpmask,ed,len表示填了第0到
因为题目中有限制某一些位必须是某一些数,所以在转移过程中如果有当前的ed!=must的时候,直接返回一个不可能的值
其它的直接去dfs过程中找即可
具体见代码
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
#define LL long long
const LL INFF = 0x3f3f3f3f3f3f3f3fll;
LL arr[20],must[20];
LL dp[1123456][20];
int N;
LL dfs(int S,int ed,int len){
if(must[len]!=-1 && must[len] != ed){
return -INFF;
}
if(len<1) return 0;
if(dp[S][ed]!=-1) return dp[S][ed];
dp[S][ed] = -INFF;
int V = S-(1<<ed);
for(int i=0;i<N;i++){
if((1<<i)&V){
dp[S][ed] = max(dp[S][ed],dfs(V,i,len-1)+arr[i]*arr[ed]);
}
}
return dp[S][ed];
}
int main(){
int T;
scanf("%d",&T);
int n,icase=1;
while(T-- && ~scanf("%d",&n)){
int lo;
memset(must,-1,sizeof(must));
for(int i=0;i<n;i++){
scanf("%I64d %d",&arr[i],&lo);
if(lo != -1){
must[lo] = i;
}
}
N = n;
LL ans = -INFF;
int Mas = (1<<n)-1;
for(int i=0;i<=Mas;i++){
for(int j=0;j<=n;j++){
dp[i][j] = -1;
}
}
for(int i=0;i<n;i++){
ans = max(ans,dfs(Mas,i,N-1));
}
printf("Case #%d:\n",icase++);
printf("%I64d\n",ans);
}
return 0;
}