ural False Mirrors(dfs)

http://acm.timus.ru/problem.aspx?space=1&num=1152

有n个阳台围城一圈,每个阳台都有若干个怪兽,一次可以打三个相邻的阳台上的怪兽,它们就会全部死去,但攻击者会受到没有死去怪兽的攻击,每个怪兽的攻击是1unit,问最后攻击者受到的最小伤害。

n <= 20,可以直接dfs过去。

1次WA,1次TLE。

WA是没看透题意,我判断的递归终止的条件是怪兽数目小于等于3,这是不对的,就算怪兽数目小于等于3,也不一定能一次打完,因为它只能打连续的怪兽,若两个怪兽之间的距离大于等于2,那么还需要一次才能打完。

TLE因为没加剪枝,dfs的过程中一旦发现已受攻击值大于最优值,就返回。

#include <stdio.h>
#include <iostream>
#include <map>
#include <set>
#include <list>
#include <stack>
#include <vector>
#include <math.h>
#include <string.h>
#include <queue>
#include <string>
#include <stdlib.h>
#include <algorithm>
#define LL __int64
#define eps 1e-12
#define PI acos(-1.0)
#define PP pair<LL,LL>
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 1000;
const int mod = 1000000009;

int a[22],vis[22];
int Min;
int n;
void dfs(int num,int sum,int att)
{
	if(att >= Min) //TLE的关键!
		return;
	if(num == 1)
	{
		Min = min(Min,att);
		return;
	}
	//判断没死的怪兽的位置是否相邻,只有相邻递归才结束
	else if(num == 2)
	{
		int p[3],cnt=0;
		for(int i = 1; i <= n; i++)
			if(!vis[i])
				p[++cnt] = i;
		if(p[2] - p[1] <= 1 || p[2]-p[1] == n-1)
		{
			Min = min(Min,att);
			return;
		}
	}
	else if(num == 3)
	{
		int p[3],cnt = 0;
		for(int i = 1; i <= n; i++)
		{
			if(!vis[i])
			{
				if(i <= n-2 && !vis[i+1] && !vis[i+2])
				{
					Min = min(Min,att);
					return;
				}
				else if(!vis[n-1] && !vis[n] && !vis[1])
				{
					Min = min(Min,att);
					return;
				}
			}
		}
	}
	for(int i = 1; i <= n; i++)
	{
		if(!vis[i])
		{
			int tmp = 0,f1 = 0,f2 = 0,t;
			vis[i] = 1;
			tmp += a[i];
			if(i > 1 && !vis[i-1])
			{
				vis[i-1] = 1;
				tmp += a[i-1];
				f1 = 1;
			}
			else if(i == 1 && !vis[n])
			{
				vis[n] = 1;
				tmp += a[n];
				f1 = 1;
			}
			if(i < n && !vis[i+1])
			{
				vis[i+1] = 1;
				tmp += a[i+1];
				f2 = 1;
			}
			else if(i == n && !vis[1])
			{
				vis[1] = 1;
				tmp += a[1];
				f2 = 1;
			}

			t = sum - tmp;
			dfs(num-1-f1-f2,t,att+t);
			vis[i] = 0;
			if(i > 1 && f1 == 1)
				vis[i-1] = 0;
			else if(i == 1 && f1 == 1)
				vis[n] = 0;
			if(i < n && f2 == 1)
				vis[i+1] = 0;
			else if(i == n && f2 == 1)
				vis[1] = 0;
		}
	}
}

int main()
{
	int sum;
	while(~scanf("%d",&n))
	{
		sum = 0;
		for(int i = 1; i <= n; i++)
		{
			scanf("%d",&a[i]);
			sum += a[i];
		}
		Min = INF;
		memset(vis,0,sizeof(vis));
		dfs(n,sum,0);
		printf("%d\n",Min);
	}
	return 0;
}
时间: 2024-11-09 23:57:45

ural False Mirrors(dfs)的相关文章

URAL 1152. False Mirrors (记忆化搜索 状压DP)

题目链接 题意 : 每一颗子弹破坏了三个邻近的阳台.(第N个阳台是与第1个相邻)射击后后的生存的怪物都对主角造成伤害- 如此,直到所有的怪物被消灭,求怎样射击才能受到最少伤害. 思路 : 状压,数据不是很大,可以爆一爆,或者DFS下去就行,枚举每一种状态. 1 //1152 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #define oo 1 << 28 6 using n

Ural 1152 False Mirrors(状压DP)

题目地址:Ural 1152 初学状压DP,原来状压只是用到了个位运算.. 很水的状压DP.注意四则运算的优先级是高于位运算的..也就是说如果既用到了四则运算,也用到了位运算,要想先算位运算的话,要将位运算加括号.因为这个地方调了好久.. 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #inc

URAL 1033 Labyrinth(DFS)

Administration of the labyrinth has decided to start a new season with new wallpapers. For this purpose they need a program to calculate the surface area of the walls inside the labyrinth. This job is just for you! The labyrinth is represented by a m

URAL 1298 knight dfs搜索

1298. Knight Time limit: 2.0 second Memory limit: 64 MB Even paratroopers have vacations. The flight to Sirius in the depths of "The Admiral Brisco" Leo Hao whiled away with chessboard. No, he did not like usual chess game, and in addition, he d

URAL 1152 Faise Mirrors 状压DP 简单题

1152. False Mirrors Time limit: 2.0 secondMemory limit: 64 MB Background We wandered in the labyrinth for twenty minutes before finally entering the large hall. The walls were covered by mirrors here as well. Under the ceiling hung small balconies wh

【DFS】算24点

[tyvj2802/RQNOJ74]算24点 描述 几十年前全世界就流行一种数字游戏,至今仍有人乐此不疲.在中国我们把这种游戏称为“算24点”.您作为游戏者将得到4个1~9之间的自然数作为操作数,而您的任务是对这4个操作数进行适当的算术运算,要求运算结果等于24.  您可以使用的运算只有:+,-,*,/,您还可以使用()来改变运算顺序.注意:所有的中间结果须是整数,所以一些除法运算是不允许的(例如,(2*2)/4是合法的,2*(2/4)是不合法的).下面我们给出一个游戏的具体例子:  若给出的4

数据结构学习笔记05图 (邻接矩阵 邻接表--&gt;BFS DFS)

数据结构之图 图(Graph) 包含 一组顶点:通常用V (Vertex) 表示顶点集合 一组边:通常用E (Edge) 表示边的集合 边是顶点对:(v, w) ∈E ,其中v, w ∈ V 有向边<v, w> 表示从v指向w的边(单行线) 不考虑重边和自回路 无向图:边是无向边(v, w) 有向图:边是有向边<v, w> 连通:如果从V到W存在一条(无向)路径,则称V和W是连通的 连通图(Connected Graph):如果对于图的任一两个顶点v.w∈V,v和w都是连通的,则称

HDU 1016 DFS

很简单的深搜 只要看出来是深搜... 注意判断最后一点是否与加一为质数 #include<stdio.h> #include<string.h> #include<algorithm> #include<map> #include<math.h> using namespace std; int n; int ans[30]; bool vis[30]; bool ok[105]; void init()///素数打表 { memset(ok,t

深度优先搜索(DFS)

定义: (维基百科:https://en.wikipedia.org/wiki/Depth-first_search) 深度优先搜索算法(Depth-First-Search),是搜索算法的一种.是沿着树的深度遍历树的节点,尽可能深的搜索树的分支.当节点v的所有边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点.这一过程一直进行到已发现从源节点可达的所有节点为止.如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止(属于盲目搜索). 基