uva 10651 Pebble Solitaire
2015-08-27 12:19
561 查看
此题不会做,看别人做法瞬间明白了(晕)
转载的连接
原题:
Pebble solitaire is an interesting game. This is a game where you are given a board with an arrangement
of small cavities, initially all but one occupied by a pebble each. The aim of the game is to remove
as many pebbles as possible from the board. Pebbles disappear from the board as a result of a move.
A move is possible if there is a straight line of three adjacent cavities, let us call them A, B, and C,
with B in the middle, where A is vacant, but B and C each contain a pebble. The move constitutes of
moving the pebble from C to A, and removing the pebble in B from the board. You may continue to
make moves until no more moves are possible.
In this problem, we look at a simple variant of this game, namely a board with twelve cavities
located along a line. In the beginning of each game, some of the cavities are occupied by pebbles. Your
mission is to find a sequence of moves such that as few pebbles as possible are left on the board.
Input
The input begins with a positive integer n on a line of its own. Thereafter n different games follow.
Each game consists of one line of input with exactly twelve characters, describing the twelve cavities of
the board in order. Each character is either ‘-’ or ‘o’ (The fifteenth character of English alphabet in
lowercase). A ‘-’ (minus) character denotes an empty cavity, whereas a ‘o’ character denotes a cavity
with a pebble in it. As you will find in the sample that there may be inputs where no moves is possible.
Output
For each of the n games in the input, output the minimum number of pebbles left on the board possible
to obtain as a result of moves, on a row of its own.
Sample Input
5
—oo——-
-o–o-oo—-
-o—-ooo—
oooooooooooo
oooooooooo-o
Sample Output
1
2
3
12
1
大意:
给你12个洞,有的洞里有可能有石子。如果一个石子隔着一个石子且相隔的地方是空的,则可以跳过。相邻的那个石子可以拿掉。问最后剩多少。
思路
刚看到这题寻思用搜索暴力求解,但是…. 如果用暴力就对不起作者的意图了,想到用dp。因为起始状态不唯一,考虑到可以从任意一个点进行dp,想到用记忆化搜索。但是如何保存状态,没想明白。后来看了别人的代码知道了要用到状态压缩(其实早就应该想到,毕竟只有12个点,数量有限),转移方程也非常见到。无非就是两个状态,要么向左移动,要么向右移动。记录下即可~
转载的连接
原题:
Pebble solitaire is an interesting game. This is a game where you are given a board with an arrangement
of small cavities, initially all but one occupied by a pebble each. The aim of the game is to remove
as many pebbles as possible from the board. Pebbles disappear from the board as a result of a move.
A move is possible if there is a straight line of three adjacent cavities, let us call them A, B, and C,
with B in the middle, where A is vacant, but B and C each contain a pebble. The move constitutes of
moving the pebble from C to A, and removing the pebble in B from the board. You may continue to
make moves until no more moves are possible.
In this problem, we look at a simple variant of this game, namely a board with twelve cavities
located along a line. In the beginning of each game, some of the cavities are occupied by pebbles. Your
mission is to find a sequence of moves such that as few pebbles as possible are left on the board.
Input
The input begins with a positive integer n on a line of its own. Thereafter n different games follow.
Each game consists of one line of input with exactly twelve characters, describing the twelve cavities of
the board in order. Each character is either ‘-’ or ‘o’ (The fifteenth character of English alphabet in
lowercase). A ‘-’ (minus) character denotes an empty cavity, whereas a ‘o’ character denotes a cavity
with a pebble in it. As you will find in the sample that there may be inputs where no moves is possible.
Output
For each of the n games in the input, output the minimum number of pebbles left on the board possible
to obtain as a result of moves, on a row of its own.
Sample Input
5
—oo——-
-o–o-oo—-
-o—-ooo—
oooooooooooo
oooooooooo-o
Sample Output
1
2
3
12
1
大意:
给你12个洞,有的洞里有可能有石子。如果一个石子隔着一个石子且相隔的地方是空的,则可以跳过。相邻的那个石子可以拿掉。问最后剩多少。
[code]#include <cstdio> #include <cstdlib> #include <cstring> #define min(a,b) (((a) < (b)) ? (a) : (b)) int dp[4100]; int solve(int n) { if (dp != -1) return dp ; dp = 0; for (int i = 0; i < 12; ++i) if (n & (1 << i)) dp += 1; for (int i = 0; i < 10; ++i) { int t; if ((n&(1<<i)) && (n&(1<<(i+1))) && !(n&(1<<(i+2)))) { t = n; t &= ~(1 << i); t &= ~(1 << (i+1)); t |= 1 << (i+2); dp = min(dp , solve(t)); } if (!(n&(1<<i)) && (n&(1<<(i+1))) && (n&(1<<(i+2)))) { t = n; t &= ~(1 << (i+1)); t &= ~(1 << (i+2)); t |= 1 << i; dp = min(dp , solve(t)); } } return dp ; } int main() { memset(dp, -1, sizeof(dp)); int cases; scanf("%d", &cases); while (cases--) { char str[20]; int n = 0; scanf("%s", str); for (int i = 0; i < 12; ++i) if (str[i] == 'o') n ^= 1 << i; printf("%d\n", solve(n)); } return 0; }
思路
刚看到这题寻思用搜索暴力求解,但是…. 如果用暴力就对不起作者的意图了,想到用dp。因为起始状态不唯一,考虑到可以从任意一个点进行dp,想到用记忆化搜索。但是如何保存状态,没想明白。后来看了别人的代码知道了要用到状态压缩(其实早就应该想到,毕竟只有12个点,数量有限),转移方程也非常见到。无非就是两个状态,要么向左移动,要么向右移动。记录下即可~
相关文章推荐
- org.artofsolving.jodconverter.office.OfficeException: failed to start and connect
- 浅谈层次化的AI架构
- IBDesignable Errors Failed to update auto layout status:……
- strong,weak, retain, assign的区别
- [转]Skia之二 —— SkPaint 篇
- 领域模型驱动设计(Domain Driven Design)入门概述
- 出现( linker command failed with exit code 1)错误总结
- UVA 253 Cube painting(思维题)
- usaco Barn Repair
- strong,weak, retain, assign的区别
- timed out waiting for input: auto-logout
- ubuntu下出现su: Authentication failture
- 2015 Multi-University Training Contest 9(hdu 5396 - hdu 5405)
- AIDL的简单示例与解析
- hdoj 1023 Train Problem II 【卡特兰数】
- RAID各级别的特性
- MainActivity 嵌入 Fragment 的每个函数执行的生命周期
- hdoj.1023 Train Problem II【卡特兰数列】 2015/08/27
- 2015.6.17(Tair)
- oc assign / copy / retain / 容器 / 多态