题目http://acm.hdu.edu.cn/showproblem.php?pid=5691

状态DP,dp[i][j],i 表示的是一种状态,这个状态指的是当前这个数取或不取,j表示的是以第j个数结尾,

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 typedef long long ll;
 8 ll dp[1<<17][20];
 9 
10 int num[20],dis[20],vis[20];
11 ll max(ll x,ll y) {return x>y?x:y;}
12 const ll INF=1e18;
13 
14 int main()
15 {
16     int t,n,pos=0;
17     scanf("%d",&t);
18     while (t--)
19     {
20         scanf("%d",&n);
21         memset(vis,-1,sizeof(vis));
22         for(int i=0;i<(1<<n);i++)
23             for(int j=0;j<n;j++)
24                 dp[i][j] = -INF;
25         for (int i=0 ; i<n ; i++) {
26             scanf("%d%d",&num[i],&dis[i]);
27             if (dis[i]!=-1)
28                 vis[dis[i]]=i;
29         }
30         if (vis[0]!=-1) dp[(1<<vis[0])][vis[0]]=0;// 0这个位子被占用了
31         else{
32             for (int i=0 ; i<n ; i++) // 没有特定位置
33                 if (dis[i]==-1) dp[(1<<i)][i]=0; //
34         }
35         int cas=(1<<n)-1;
36         for (int i=1 ; i<=cas ; i++){
37             int ans=0;
38             for (int j=0 ; j<n ; j++)
39                 if (i&(1<<j))
40                    ans++;
41             if (vis[ans]!=-1)
42             {
43                 ans=vis[ans];
44                 for (int j=0 ; j<n ; j++)
45                     if ((i&(1<<j))&&j!=ans)
46                         dp[i|(1<<ans)][ans]=max(dp[i|(1<<ans)][ans],dp[i][j]+num[j]*num[ans]);
47             }
48             else
49             {
50                for (int j=0 ; j<n ; j++){
51                    if (i&(1<<j)){
52                       for (int k=0 ; k<n ; k++){
53                           if (!(i&(1<<k))){
54                               dp[i|(1<<k)][k]=max(dp[i|(1<<k)][k],dp[i][j]+num[k]*num[j]);
55                           }
56                       }
57                    }
58                }
59             }
60         }
61         printf("Case #%d:\n",++pos);
62         ll maxn=-INF;
63         for (int i=0 ; i<n ; i++)
64             maxn=max(maxn,dp[cas][i]);
65         printf("%I64d\n",maxn);
66     }
67     return 0;
68 }
View Code

 

posted on 2016-07-13 14:59  蜘蛛侦探  阅读(227)  评论(0编辑  收藏  举报