zoj 3471 Most Powerful(状态压缩dp)

Recently, researchers on Mars have discovered N powerful atoms. All of them are different. These atoms have some properties. When two of these atoms collide, one of them disappears and a lot of power is produced. Researchers know the way every two atoms perform when collided and the power every two atoms can produce.

You are to write a program to make it most powerful, which means that the sum of power produced during all the collides is maximal.

Input

There are multiple cases. The first line of each case has an integer N (2 <= N <= 10), which means there are N atoms: A1, A2, ... , AN. Then N lines follow. There are N integers in each line. The j-th integer on the i-th line is the power produced when Ai and Aj collide with Aj gone. All integers are positive and not larger than 10000.

The last case is followed by a 0 in one line.

There will be no more than 500 cases including no more than 50 large cases that N is 10.

Output

Output the maximal power these N atoms can produce in a line for each case.

Sample Input

2
0 4
1 0
3
0 20 1
12 0 1
1 10 0
0

Sample Output

4
22

枚举所有的状态,0表示存在,1表示不存在(已经与别的气球产生能量并且消失)。然后就是枚举所有的状态(第一个for循环),再在里面两重循环i和j,i表示不消失的那个,j表示消失的那个气球,得到了一个新的状态newS=S+(1<<j),最后就是dp[newS]=max(dp[newS],dp[S]+mp[i][j]);  边界条件是dp[S]=0,   注意这些条件(1、if(S&(1<<i)) continue;         2、if(i==j)continue;     3、if(S&(1<<j)) continue;)

 1 #pragma comment(linker, "/STACK:1024000000,1024000000")
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<math.h>
 7 #include<algorithm>
 8 #include<queue>
 9 #include<set>
10 #include<bitset>
11 #include<map>
12 #include<vector>
13 #include<stdlib.h>
14 using namespace std;
15 #define max(a,b) (a) > (b) ? (a) : (b)
16 #define min(a,b) (a) < (b) ? (a) : (b)
17 #define ll long long
18 #define eps 1e-10
19 #define MOD 1000000007
20 #define N 16
21 #define M 1<<N
22 #define inf 1e12
23 int n;
24 int mp[N][N];
25 int dp[M];
26 int main()
27 {
28     while(scanf("%d",&n)==1){
29         if(n==0) break;
30         for(int i=0;i<n;i++){
31             for(int j=0;j<n;j++){
32                 scanf("%d",&mp[i][j]);
33             }
34         }
35
36         memset(dp,0,sizeof(dp));
37         for(int S=0;S<(1<<n);S++){
38             for(int i=0;i<n;i++){
39                 if(S&(1<<i)) continue;
40                 for(int j=0;j<n;j++){
41                     if(i==j) continue;
42                     if(S&(1<<j)) continue;
43                     int newS=S+(1<<j);
44                     dp[newS]=max(dp[newS],dp[S]+mp[i][j]);
45                 }
46             }
47         }
48         int ans=0;
49         for(int i=0;i<(1<<n);i++){
50             ans=max(ans,dp[i]);
51         }
52         printf("%d\n",ans);
53     }
54     return 0;
55 }

时间: 2024-08-08 02:15:05

zoj 3471 Most Powerful(状态压缩dp)的相关文章

ZOJ - 3471 Most Powerful (状态压缩)

题目大意:有n种原子,两种原子相碰撞的话就会产生能量,其中的一种原子会消失.问这n种原子能产生的能量最大是多少 解题思路:用0表示该原子还没消失,1表示该原子已经消失,那么就可以得到状态转移方程了 dp[state | (1 << i)] = max(dp[state | (1 << i)], dp[state] + power[j][i]) 上面的方程表示的是在state的情况下,用j原子去碰撞i原子,i原子消失所能得到的最大能量 注意这题:产生的能量有可能是负的 #includ

ZOJ 3471 Most Powerful 状压DP

水题,一维的DP,表示还剩哪些atom的时候能获得的最大能量 #include <cstdio> #include <cstring> #include <iostream> #include <map> #include <set> #include <vector> #include <string> #include <queue> #include <deque> #include <

ZOJ 3471 Most Powerful(状压DP)

Description Recently, researchers on Mars have discovered N powerful atoms. All of them are different. These atoms have some properties. When two of these atoms collide, one of them disappears and a lot of power is produced. Researchers know the way

ZOJ3471 状态压缩DP

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3471 Recently, researchers on Mars have discovered N powerful atoms. All of them are different. These atoms have some properties. When two of these atoms collide, one of them disappears and

zoj 3471 Most Powerful

题目链接:zoj 3471 Most Powerful 很经典的状态dp,使用i的二进制位表示粒子的状态,0表示存在,1表示不存在.dp[i]表示在状态i的情况下能够释放的最大的能量,注意自身不能够发生碰撞.例如4个粒子的状态1100表示第0个和第1个粒子不存在,第2.3个粒子存在则可以转移到状态1110或1101.最终遍历只剩下一颗粒子的情况下的所有能量中的最大值. 代码如下: 1 #include <cstdio> 2 #include <cstdlib> 3 #include

POJ 3254 Corn Fields 状态压缩DP (C++/Java)

http://poj.org/problem?id=3254 题目大意: 一个农民有n行m列的地方,每个格子用1代表可以种草地,而0不可以.放牛只能在有草地的,但是相邻的草地不能同时放牛, 问总共有多少种方法. 思路: 状态压缩的DP. 可以用二进制数字来表示放牧情况并判断该状态是否满足条件. 这题的限制条件有两个: 1.草地限制. 2.相邻限制. 对于草地限制,因为输入的时候1是可以种草地的. 以"11110"草地分析,就只有最后一个是不可以种草的.取反后得00001  .(为啥取反

HDU1565(状态压缩dp)

方格取数(1) Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 8170    Accepted Submission(s): 3095 Problem Description 给你一个n*n的格子的棋盘,每个格子里面有一个非负数.从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数

HDU 3001【状态压缩DP】

题意: 给n个点m条无向边. 要求每个点最多走两次,要访问所有的点给出要求路线中边的权值总和最小. 思路: 三进制状态压缩DP,0代表走了0次,1,2类推. 第一次弄三进制状态压缩DP,感觉重点是对数据的预处理,利用数组分解各个位数,从而达到类似二进制的目的. 然后就是状态的表示,dp[s][i]表示状态s时到达i的最优值. 状态转移也一目了然,不废话. #include<stdio.h> #include<string.h> #include<algorithm> u

Victor and World(spfa+状态压缩dp)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5418 Victor and World Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/131072 K (Java/Others)Total Submission(s): 958    Accepted Submission(s): 431 Problem Description After trying hard fo

poj 3311 Hie with the Pie(状态压缩dp)

Description The Pizazz Pizzeria prides itself in delivering pizzas to its customers as fast as possible. Unfortunately, due to cutbacks, they can afford to hire only one driver to do the deliveries. He will wait for 1 or more (up to 10) orders to be