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 namespace std ;
 7
 8 int a[110],dp[1 << 21] ;
 9 bool vis[1 << 21] ;
10 int n ;
11
12 int DFS(int sta,int sum)
13 {
14     if(vis[sta]) return dp[sta] ;
15     vis[sta] = true ;
16     if(sta == 0) return dp[sta] = 0 ;
17     int ans = oo ;
18     for(int i = 0 ; i < n ; i++)
19     {
20         int newsta = sta ,newsum = sum ;
21         for(int j = i-1 ; j <= i+1 ; j++)
22         {
23             int k = j ;
24             if(j == -1) k = n-1 ;
25             else if(j == n) k = 0 ;
26             if(newsta & (1 << k))
27             {
28                 newsta -= (1 << k) ;
29                 newsum -= a[k] ;
30             }
31         }
32         if(newsta != sta)
33             ans = min(ans,DFS(newsta,newsum)+newsum) ;
34     }
35     return dp[sta] = ans ;
36 }
37 int main()
38 {
39     while(~scanf("%d",&n))
40     {
41         int sum = 0 ;
42         memset(a,0,sizeof(a)) ;
43         memset(dp,63,sizeof(dp)) ;
44         memset(vis,false,sizeof(vis)) ;
45         for(int i = 0 ; i < n ; i++)
46         {
47             scanf("%d",&a[i]) ;
48             sum += a[i] ;
49         }
50         dp[(1 << n)-1] = 0 ;
51         printf("%d\n",DFS((1 << n)-1,sum)) ;
52     }
53     return 0 ;
54 }

时间: 2024-10-17 03:29:23

URAL 1152. False Mirrors (记忆化搜索 状压DP)的相关文章

HDU 4778 记忆化搜索&amp;状压

给出G种宝石,B个包,和S,S代表到时候每种颜色的宝石凑齐S个能变成一个魔法石 每个包里有N种宝石,分别为c1,c2....... 然后两人轮流拿包,每个包只能拿一次,拿出包把宝石放地上. 如果能变成魔法石则拿走魔法石,下一次还这个人拿包,没变成则换人. 魔法石的个数就是获得分数,问两人最优的时候分差是多少. 状压记忆化搜索 一共21个包,状压存当前取包的状态 无论怎样取,最后获得的魔法石数量一定 dp[i]表示在i状态下,先手可以获得的最高分数 #include "stdio.h"

lightoj1061 (N Queen Again)搜索+状压dp

题意:(八皇后问题的变形)给定8个皇后的位置,然后问最少要走几步使得每个皇后之间可以不相互攻击(不在同一行同一列同一斜线).其中走的过程每步可以横着竖着斜着走多个格子. 解法:先枚举所有合法的八皇后局面(总共92种).然后将给的点对合法八皇后局面进行匹配.dp[i][j]表示合法八皇后前i个点用掉给定八皇后集合的子集j所花费的最小步数.这里的匹配相当于两个集合各八个点,进行一一配对.原来想的是ans[i][j]的i是合法皇后状态子集,但是这样会有增加好多复杂度.前边的dp[i][j]可以在8*2

Ural 1152 False Mirrors(状压DP)

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

HDU 1978 记忆化搜索(dfs+dp)

Y - How many ways Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 1978 Appoint description: Description 这是一个简单的生存游戏,你控制一个机器人从一个棋盘的起始点(1,1)走到棋盘的终点(n,m).游戏的规则描述如下: 1.机器人一开始在棋盘的起始点并有起始点所标有的能量. 2.机器

记忆化搜索+DFS URAL 1183 Brackets Sequence

题目传送门 1 /* 2 记忆化搜索+DFS:dp[i][j] 表示第i到第j个字符,最少要加多少个括号 3 dp[x][x] = 1 一定要加一个括号:dp[x][y] = 0, x > y; 4 当s[x] 与 s[y] 匹配,则搜索 (x+1, y-1); 否则在x~y-1枚举找到相匹配的括号,更新最小值 5 */ 6 #include <cstdio> 7 #include <algorithm> 8 #include <cmath> 9 #include

wenbao与记忆化搜索

记忆化搜索: 通俗地讲就是搜索的形式,dp的思想 一些搜索难以完成,dp的动态转移方程又不好写的题,就会用到记忆化搜索,利用dp记录路径(相当于为dfs剪枝)用dfs进行模拟.. 啦啦啦啦啦啦,,,,,,,,,好厉害!!!!!! @ https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1059 弱鸡代码 1 #include <strin

背包问题 (记忆化搜索)

使用记忆化搜索,可大大提升时间效率.... 1 int n,W;//n为重量 2 int w[MAX],v[MAX]; 3 int dp[MAX][MAX]; 4 5 //从第i个物品开始挑选总重小于j的部分 6 int rec(int i,int j) 7 { 8 //记忆化搜索 9 /*if(dp[i][j] >= 0){ 10 return dp[i][j]; 11 }*/ 12 int rec; 13 if(i==n){ 14 //已经没有剩余物品了 15 rec=0; 16 } 17

UVALive 6470 Chomp --记忆化搜索

题意:给一个只有三行的方块阵(横向最多100个),然后p,q,r分别代表第1,2,3层的方格数,两人轮流去掉一个格子,此时这个格子的右上方都会被去掉,面临只剩最左下角的一个格子的状态的人输,问先手能否赢,要赢得话应该取哪个方格. 解法:记忆化搜索,设dp[p][q][r]表示第1,2,3层方格数分别为p,q,r的输赢状态,0为输,1为赢,X[][][],Y[][][]分别表示其该取的方格坐标.每次求dp[p][q][r]时,枚举能达到的状态,如果这些状态的输赢值有一个为输,则此状态一定为赢,返回

记忆化搜索(DFS+DP) URAL 1501 Sense of Beauty

题目传送门 1 /* 2 题意:给了两堆牌,每次从首部取出一张牌,按颜色分配到两个新堆,分配过程两新堆的总数差不大于1 3 记忆化搜索(DFS+DP):我们思考如果我们将连续的两个操作看成一个集体操作,那么这个操作必然是1红1黑 4 考虑三种情况:a[]连续两个颜色相同,输出11:b[]连续两个相同,输出22: 5 a[x] != b[y], 输出12:否则Impossible 6 详细解释:http://blog.csdn.net/jsun_moon/article/details/10254