题目大意:中文就略了吧
思路:按照状压dp思想,罗列0-(1<<16-1)状态(i),只不过这里的状态是指选中的人按顺序排列;然后枚举可以排在最后的人(j)。对于特殊情况的处理,如果只有一个人,结果为0;如果最后一个人在i的状态下顺序排列的位置与固定状态下应该站的位置不同,则只为不可到达,即负无穷。pos数组记录的 i 表示成二进制有多少个1,对应顺序排一共可以排多少人
/************************************************************** Problem:hdu 5691 User: youmi Language: C++ Result: Accepted Time:1794MS Memory:6972K ****************************************************************/ //#pragma comment(linker, "/STACK:1024000000,1024000000") //#include<bits/stdc++.h> #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <map> #include <stack> #include <set> #include <sstream> #include <cmath> #include <queue> #include <deque> #include <string> #include <vector> #define zeros(a) memset(a,0,sizeof(a)) #define ones(a) memset(a,-1,sizeof(a)) #define sc(a) scanf("%d",&a) #define sc2(a,b) scanf("%d%d",&a,&b) #define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c) #define scs(a) scanf("%s",a) #define sclld(a) scanf("%I64d",&a) #define pt(a) printf("%d\n",a) #define ptlld(a) printf("%I64d\n",a) #define rep(i,from,to) for(int i=from;i<=to;i++) #define irep(i,to,from) for(int i=to;i>=from;i--) #define Max(a,b) ((a)>(b)?(a):(b)) #define Min(a,b) ((a)<(b)?(a):(b)) #define lson (step<<1) #define rson (lson+1) #define eps 1e-6 #define oo 0x3fffffff #define TEST cout<<"*************************"<<endl const double pi=4*atan(1.0); using namespace std; typedef long long ll; int n; const int maxn=80000+10; int a[20],p[20]; int bit; int dp[maxn][20]; int pos[maxn]; void init() { int now=1<<16; for(int i=0;i<now;i++) { int temp=i; int cnt=0; while(temp) { if(temp&1) cnt++; temp>>=1; } pos[i]=cnt; } } void solve() { for(int i=0;i<=bit;i++) for(int j=1;j<=n;j++) dp[i][j]=-oo; for(int i=0;i<=bit;i++) { for(int j=1;j<=n;j++) { int temp=1<<(j-1); if(i&temp) { if(p[j]!=-1&&p[j]!=pos[i]-1) dp[i][j]=-oo; else if(i==temp) dp[i][j]=0; else { for(int k=1;k<=n;k++) { if(k!=j&&(i&(1<<(k-1)))&&dp[i^temp][k]!=-oo) dp[i][j]=Max(dp[i][j],dp[i^temp][k]+a[j]*a[k]); } } } } } int ans=-oo; for(int i=1;i<=n;i++) ans=Max(dp[bit][i],ans); printf("%d\n",ans); } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif int T_T; scanf("%d",&T_T); init(); for(int kase=1;kase<=T_T;kase++) { printf("Case #%d:\n",kase); sc(n); bit=(1<<n)-1; rep(i,1,n) { sc2(a[i],p[i]); } solve(); } }
不为失败找借口,只为成功找方法