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 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

这个题目对于每个粒子有存在和消失两种状态,自然总的状态数有2^n种。

对于某种状态,如果用普通的表示,自然有dp[0][1][0]……[1](其中1表示存在,0表示消失),因为每个粒子只有0和1两种值,此处采用二进制进行状态压缩。

接下来考虑对于某个状态10001011,如果第一1要变成0,自然是考虑这个粒子和现存的粒子进行碰撞,然后找能达到的最大值。我们记这个值为GetMax(state, now)(其中state是当前二进制状态,now是由1转为0的那一位)。

于是考虑状态转移方程,对于状态10001,必然由状态11001或10101或10011转换而来,自然对于state,可以由某个0位变成1的状态forestate转换而来。所以:

dp[state] = max{dp[forestate] + GetMax(forestate, now)}

此处采用记忆化搜索进行求解。初始状态M = (1<<n)^0。

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring> using namespace std; int n, M;
int p[15][15];
int dp[1500]; void Input()
{
memset(dp, 0, sizeof(dp));
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
scanf("%d", &p[i][j]);
M = (M<<n)^0;
} int GetMax(int state, int now)
{
int Max = 0;
for (int i = 0; i < n; ++i)
if (state&(1<<i))
Max = max(Max, p[i+1][now]);
return Max;
} void Dfs(int state)
{
if (state == M)
{
dp[state] = 0;
return;
}
int Max = 0, t;
for (int i = 0; i < n; ++i)
{
if ((state&(1<<i)) == 0)
{
if (dp[state|(1<<i)] == 0)
Dfs(state|(1<<i));
t = dp[state|(1<<i)] + GetMax(state, i+1);
Max = max(Max, t);
}
}
dp[state] = Max;
} int Work()
{
int ans = 0;
for (int i = 0; i < n; ++i)
{
Dfs(1<<i);
ans = max(ans, dp[1<<i]);
}
return ans;
} int main()
{
//freopen("test.in", "r", stdin);
while (scanf("%d", &n) != EOF && n)
{
Input();
printf("%d\n", Work());
}
return 0;
}

ACM学习历程—ZOJ3471 Most Powerful(dp && 状态压缩 && 记忆化搜索 && 位运算)的更多相关文章

  1. loj 1011(状态压缩+记忆化搜索)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=25837 思路:状态压缩+记忆化搜索. #include<io ...

  2. HDU 4628 Pieces(状态压缩+记忆化搜索)

    http://acm.hdu.edu.cn/showproblem.php?pid=4628 题意:给个字符窜,每步都可以删除一个字符窜,问最少用多少步可以删除一个字符窜分析:状态压缩+记忆化搜索  ...

  3. Doing Homework---hdu1074(状态压缩&&记忆化搜索)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1074 有n(n<=15)门课需要做作业,每门课所需时间是used_time以及每门课作业上交的最 ...

  4. light oj 1011 - Marriage Ceremonies (状态压缩+记忆化搜索)

    题目链接 大概题意是有n个男的n个女的(原谅我这么说,我是粗人),给你一个n*n的矩阵,第i行第j列表示第i个女(男)对第j个男(女)的好感度,然后要安排n对相亲,保证都是正常的(无搞基百合之类的), ...

  5. GYM 101933E 状态压缩 + 记忆化搜索

    题意:我方有n个士兵,敌方有m个,每方士兵都有一个血量,现在有k轮无差别炮火打击,每次都会从存活的士兵中随机选一人,这名士兵的HP就-1,问对方被团灭的概率有多大? 思路:因为n和m的范围很小,我们可 ...

  6. NYOJ16|嵌套矩形|DP|DAG模型|记忆化搜索

    矩形嵌套 时间限制:3000 ms  |  内存限制:65535 KB 难度:4   描述 有n个矩形,每个矩形可以用a,b来描述,表示长和宽.矩形X(a,b)可以嵌套在矩形Y(c,d)中当且仅当a& ...

  7. ACM学习历程—POJ1088 滑雪(dp && 记忆化搜索)

    Description Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你.Michael想知道 ...

  8. poj1191 棋盘分割【区间DP】【记忆化搜索】

    棋盘分割 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16263   Accepted: 5812 Description ...

  9. 状态压缩中常用的位运算(DP)

    面对位运算,一直很无感...可能数学太差,脑洞太小. 1.首先是最基本的: 与&,或|,非~,异或^. 2.获取一个或者多个固定位的值: 假设 x = 1010(二进制),我们要取左数第二位的 ...

随机推荐

  1. nodejs初学-----helloworld

    近期紧锣密鼓的学习了下nodejs(之前在学php.算入门了吧,可是时间关系,还没写文章,兴许要搞安卓和大数据,总之比較忙哈,计划上php要排到后面了,还请广大小伙伴不要着急) 先抄一句:Node.j ...

  2. Linux U盘只读解决方法

    Linux Fat的U盘只读,这个问题经常出现,原因大家都说了是U盘的错误,出现这种情况后,一般的解决方案是 mount | grep <U盘的标签> # 找到你的U盘的对应的设备名称,如 ...

  3. 转:MSN君最后的十个瞬间

    五年前我用过MSN五年.在一家ERP公司当程序猿的时候我甚至在业余时间做过一款MSN订餐机器人. 转完这篇文章.就是真正跟MSN的bye bye了. 转自:www.gogo.cn 今天是一个普通的周五 ...

  4. golang中并发sync和channel

    golang中实现并发非常简单,只需在需要并发的函数前面添加关键字"go",但是如何处理go并发机制中不同goroutine之间的同步与通信,golang 中提供了sync包和channel ...

  5. ASP.NET MVC 4 技术讲解

    ASP.NET MVC 相关的社群与讨论区 Routing 与 ASP.NET MVC 生命周期 Model相关技术 Controller相关技术 View数据呈现相关技术 Area区域相关技术 AS ...

  6. Emgu安装配置及使用

    前言:项目需要,需使用图像处理来完成机械臂从运动的皮带上抓取物体的功能,所以又重拾视觉与图像处理内容. 内容:Emgu是OpenCV的一个跨平台的.NET封装,结构如下图所示: 下载地址:http:/ ...

  7. vs中使用M_PI的问题及解决 角度转弧度&根据弧度计算圆周上点的坐标的方法

    M_PI 是一个宏定义,圆周率的定义           C/C++ code #define M_PI 3.14159265358979323846 此宏定义和编译器有关,TC中M_PI宏就定义在& ...

  8. python之Matplotlib 和Numpy

    1.matplotlib http://www.cnblogs.com/TensorSense/p/6802280.html https://wenku.baidu.com/view/e1c15c9d ...

  9. angularcli填坑系列(持续更新...)

    1.在xx.ts中引入css样式无效 @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls ...

  10. Python中属性

    属性定义的两种方式: 1.num1=property(GetNum,SetNum)   class Pro(): def __init__(self): self._num= def GetNum(s ...