您的位置:首页 > 其它

2016"百度之星" - 初赛(Astar Round2A)1002(dp状压)

2016-05-21 21:45 387 查看
题目链接:点这里!!!!!

题意:中文题。

题解:

参考别人的。。。。

设dp[i][j]为i这个状态下以a[j]结尾的情况下的最大值。

dp[i][j]可以转变成dp[i|(1<<k)][k],我们只要注意第k数有没有被固定就可以。

dp[i|(1<<k)][k]=max(dp[i|(1<<k)][k],dp[i][j]+a[j]*a[k])。

时间复杂度为O(n*n*2^n)。

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<sstream>
#include<algorithm>
#include<vector>
#include<bitset>
#include<set>
#include<queue>
#include<stack>
#include<map>
#include<cstdlib>
#include<cmath>
#define LL long long
#define pb push_back
#define pa pair<int,int>
#define clr(a,b) memset(a,b,sizeof(a))
#define lson lr<<1,l,mid
#define rson lr<<1|1,mid+1,r
#define bug(x) printf("%d++++++++++++++++++++%d\n",x,x)
#define key_value ch[ch[root][1]][0]
#define bitnum(a) __builtin_popcount(a)
#pragma comment(linker, "/STACK:102400000000,102400000000")
const LL  MOD = 1000000007;
const int N = 1e5+15;
const int maxn = 8e3+15;
const int letter = 130;
const LL INF = 1e18;
const double pi=acos(-1.0);
const double eps=1e-10;
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
LL dp[1<<18][18],a[18];
int n,vs[18];
int main(){
int T,p,cas=0;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
clr(vs,-1);
for(int i=0;i<n;i++){
scanf("%I64d%d",a+i,&p);
if(p!=-1)vs[p]=i;
}
for(int i=0;i<(1<<n);i++)
for(int j=0;j<n;j++)dp[i][j]=-INF;
///init
if(vs[0]!=-1) dp[1<<(vs[0])][vs[0]]=0;
else for(int i=0;i<n;i++) dp[1<<i][i]=0;
for(int i=1;i<(1<<n);i++){
for(int j=0;j<n;j++){///j结尾
if(i&(1<<j)){
for(int k=0;k<n;k++){///k没选
if((i&(1<<k))==0){
int cnt = bitnum(i);
if(vs[cnt]==-1||vs[cnt]==k){
dp[i|(1<<k)][k]=max(dp[i|(1<<k)][k],dp[i][j]+a[j]*a[k]);
}
}
}
}
}
}
LL max1=-INF;
for(int i=0;i<n;i++) max1=max(max1,dp[(1<<n)-1][i]);
printf("Case #%d:\n%I64d\n",++cas,max1);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: