zoj3471 Most Powerful(状态压缩)

题目 : http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3471

题意:有n个原子,题目输入一个矩阵map[n][n],map[i][j]表示用原子i和原子j碰撞所产生的能量,原子i 撞击 原子j 后 原子j 消失。

问这n个原子碰撞后 能产生的最大能量是多少?

思路:状态dp[s] 表示到达状态s产生的最大能量,已经被碰撞消失的原子,所在二进制位置为0

初始化 dp[1<<(i-1)] = 0 表示 只剩一个原子时候,最大产生的能量是0

转移:二重循环遍历所有原子,用 i 去 撞击 j。

这里我为了快点写出代码,直接用了 深搜+记录

#include<stdio.h>
#include<memory.h>
const int maxn = 10+1;
int dp[1<<maxn];
int map[maxn][maxn];
int bb[maxn];
int end;
int n;
int dfs(int s)
{
	if(dp[s]!=-1) 
	{
		return dp[s];	
	}
	int rs = -1;
	for(int i=1;i<=n;i++)//用i去引爆j 
	{
		if((s&(1<<(i-1)))==0) continue;
		for(int j=1;j<=n;j++)
		{
			if(i==j)continue;
			if((s&(1<<(j-1)))==0) continue;
			
			int tmp = map[i][j] + dfs(s-(1<<(j-1)));
			if(rs < tmp) rs = tmp;
		}
	}
	dp[s] = rs;
	return rs;
}
int main()
{
	while(true)
	{
		scanf("%d",&n);
		if(n==0) break;
		memset(dp,-1,sizeof(dp));
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
				scanf("%d",&map[i][j]);
		for(int i=1;i<=n;i++)//引爆i 
		{
			bb[i] = map[1][i];
			for(int j=2;j<=n;j++)//用j去引爆 
			{
				if(bb[i]<map[j][i])
				{
					bb[i] = map[j][i];
				}
			}
		}
		end = (1<<n)-1; 
		for(int i=1;i<=n;i++)
			dp[(1<<(i-1))] = 0;
		printf("%d\n",dfs(end));	
	}
	return 0;
}

渣科,继续好好加油吧。

猜你喜欢

转载自blog.csdn.net/zark721/article/details/81085444