hdu 4049 Tourism Planning 状态压缩dp

http://acm.hdu.edu.cn/showproblem.php?pid=4049   

【题意】 一群人 去n个城市旅游  每个城市有一个消费cost,每个人的cost 都相同。每个人i对城市j都有一个喜爱的值inter[i][j]。他们的路线及起点终点都已经确定。每一个人都有权中途离开队伍,或者干脆第一座城市就不去,但是一旦离开就不可以再回来. 一群人呆在一起 兴趣可以增加 增加的值为 两两的b值之和。 求可以获得的(inter-cost) 的最大值 若其不大于0 就输出 stay home

【思路】 二进制state 第i位为1 代表第i个人在队伍里 ,到第i个城市的时候 队伍里的人的状态为state

                  dp[i][state]=   max(dp[i-1][j]+sum(i,state));  ( ( state&j)==state )     // 在第i-1 个城市时 状态为j  即state 里的人都在  没在state 里的人也可能在

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<queue>
 4 #include<cstdio>
 5 #include<string.h>
 6 
 7 #define maxx 1<<11
 8 using namespace std;
 9 int m,n,dp[11][maxx],inter[11][11],b[11][11],cost[11];
10 bool vis[11];
11 
12 int sum(int k,int state)//  第k座城市 状态为state时
13 {
14     memset(vis,false,sizeof(vis));
15     for(int i=0;i<n;i++)
16     {
17         int temp;
18         temp=1<<i;
19         if(state&temp)
20             vis[n-i-1]=true;
21 
22     }
23     int ans=0;
24     for(int i=0;i<n;i++)//第i个人
25         if(vis[i])
26             ans+=inter[i][k];
27     for(int i=0;i<n;i++)
28         for(int j=i+1;j<n;j++)
29             if(vis[i]&&vis[j])
30                 ans+=b[i][j];
31     for(int i=0;i<n;i++)
32         if(vis[i])
33             ans-=cost[k];
34     return ans;
35 
36 }
37 
38 
39 int solve()
40 {
41     memset(dp,0,sizeof(dp));
42     int nowmax;
43     nowmax=1<<n;
44     for(int i=0;i<nowmax;i++)//{
45         dp[0][i]=sum(0,i);//printf("00000000000  %d %d
",i,dp[0][i]);}
46 
47     for(int i=1;i<m;i++)
48         for(int state=0;state<nowmax;state++)//求dp[i][state]
49         {
50             int max1;
51             max1=-10000000;
52             for(int j=0;j<nowmax;j++)
53             {
54                 if((state&j)==state)
55                     max1=max(max1,dp[i-1][j]);
56             }
57             dp[i][state]=max1+sum(i,state);
58         }
59         int ans=-1;
60         for(int i=0;i<nowmax;i++)
61             if(dp[m-1][i]>ans)
62                 ans=dp[m-1][i];
63         return ans;
64 }
65 
66 
67 int main()
68 {
69     while(~scanf("%d%d",&n,&m))
70     {
71         if(n==0&&m==0)
72             break;
73         for(int i=0;i<m;i++)
74             scanf("%d",&cost[i]);
75         for(int i=0;i<n;i++)
76             for(int j=0;j<m;j++)
77                 scanf("%d",&inter[i][j]);
78         for(int i=0;i<n;i++)
79             for(int j=0;j<n;j++)
80                 scanf("%d",&b[i][j]);
81         int p;
82         p=solve();
83         if(p>0)
84             printf("%d
",p);
85         else printf("STAY HOME
");
86     }
87     return 0;
88 }
原文地址:https://www.cnblogs.com/assult/p/3741467.html