HDU 3469 Catching the Thief (博弈 + DP递推)

Catching the Thief

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 653    Accepted Submission(s): 359

Problem Description

In the Qingshui Village, there‘s a clever thief and a cleverer police.

There are N houses in Qingshui Village which are located in a straight line. And the N houses are numbered from 1 to N according to the direction of the line. Two houses are consided to be neighbor of each other if and only if there is no other house between
them.

The thief hides in one of N houses now, and the police tries to find him out. Every day the police will choose a house to check and he will catch the thief if he hides in that house. If the thief survive the arrest of the police, in the night he will move to
a neighboring house to pass through the next day.

What is the number of days the police needs to catch the thief in the worst case?

Remember that the police is a clever man.

Input

In the first line, an integer T (T <= 100) indicates the number of cases.

T lines follow. Each contains an integer N described above. (1 <= N <= 10000)

Output

For each test case, output “Case x: d” in which x is the number of test case counted from one, and d is the number of days before the police catch the thief in the worst case.

Sample Input

2
1
2

Sample Output

Case 1: 1
Case 2: 2

Hint

Case 1: There is only one room, so the police can catch the thief on the first day.
Case 2: There are two rooms. The police can check room 1 on the first day. The worst case is that the thief is in room 2, but in this case the police
 can check room 1 on the second day and will catch the thief for sure.

这道题目首先要解出前面四个的解

房间为一个的时候答案为1天

房间为两个的时候答案为2天

房间为三个的时候答案为2天

房间为四个的时候答案为4天

第五个房子则可以递推,如下图

从左往右走,一步步排除,小偷所在的房子,dp[2]代表着两个房间里最多用多少天能够抓住小偷,如此,我们可以不断递推,先排除,左边两个房间会出现小偷的情况,接着右边还有三个房子,但是为什么图中将第二个房子都给画圈了,因为我们排除了最左边的房子不会出现小偷,但是此时无法防止第二个房子不会再出现小偷,如此要将他算进去,所以dp[5] = dp[2] + dp[4]如此不断递推得出最终的状态转移方程

dp[n] = dp[2] + dp[n - 1]


#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int MAXN = 10000 + 5;
LL dp[MAXN];
int n, T;
void init(){
    dp[1]=1;
    dp[2] = 2;
    dp[3] = 2;
    for(int i = 4;i < MAXN;i ++){
        dp[i] = dp[2] + dp[i - 1];
    }
}
int main(){
    init();
    int cas = 1;
    scanf("%d", &T);
    while(T --){
        scanf("%d", &n);
        printf("Case %d: %I64d\n",cas ++, dp[n]);
    }
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-09 22:18:01

HDU 3469 Catching the Thief (博弈 + DP递推)的相关文章

hdu 1207 汉诺塔II (DP+递推)

汉诺塔II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4529    Accepted Submission(s): 2231 Problem Description 经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往

HDU Tickets(简单的dp递推)

Tickets Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 972    Accepted Submission(s): 495 Problem Description Jesus, what a great movie! Thousands of people are rushing to the cinema. However,

uva10404 - Bachet&#39;s Game(博弈,递推)

题目:uva10404 - Bachet's Game(博弈,递推) 题目大意:stan和ollie两个小伙伴在玩石头的游戏:给出N个石头,然后给出M个数.要求每次都是stan先开始,每次拿走m (是M个数中的其中一个)个石头.谁拿走石头后桌上没有剩下石头就赢了. 解题思路:博弈.对于j个石头,stan想要赢的话那么就要分奇数次将j个石头拿走. 假设j个石头这个时候是stan赢,那么j + m个石头就是ollie赢.这样的话,让d[j] = 1代表stan赢,等于0代表ollie赢,只要能够找到

hdu2089(数位DP 递推形式)

不要62 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 25802    Accepted Submission(s): 8967 Problem Description 杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer).杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以

CodeForces 372B 脑洞大开的DP递推

题目: 做了两个多小时,脑洞大开,给了一个01矩阵,求以a,b,为左上角,c,d为右下角的矩阵内有多少包含部分全为0的子矩阵 对于这道题目,一开始就想到了DP递推,感觉而已,虽然准,可是做不出啊,想好了递推式子可是细节部分没办法去处理.看了CF上的题解,顿时脑洞大开,这个做法真的是太厉害了,这方法代码简洁明了,同时也提醒到了我,在方程假设出来后,对于转移的细节处理, 其实一开始我想到过这个递推式子 dp[i][j][k][l] += dp[i][j][k - 1][l] + dp[i][j][k

D. Caesar&#39;s Legions 背包Dp 递推DP

http://codeforces.com/problemset/problem/118/D 设dp[i][j][k1][k2] 表示,放了i个1,放了j个2,而且1的连续个数是k1,2的连续个数是k2 如果这样写,用dfs写是很简单的.但是超时,我记忆化不到 如果用递推写,对于每一个状态,更新到下一个状态. 如果放的是1,那么新的状态是dp[i + 1][j][k1 + 1][0]也就是,用多了一个1,而且连续的个数也增加了.同时,2的连续个数就打破了,变成了0 这种枚举旧状态,更新下一个状态

HDU 4944 FSF’s game(数论+递推)

#include <cstdio> #include <cstring> typedef unsigned long long ll; const ll MOD = (1ULL<<32); const int N = 500001; int t, n; ll ans[N], frc[N]; void init() { for (ll i = 1; i < N; i++) { for (ll j = i; j < N; j += i) { ll tmp = j

HDU 1165 Eddy&#39;s research II(递推)

坑了我好久,乍看很简单,记忆化搜索结果爆栈,然后改成递推之后WA . 后来发现,是在计算m=3的数据时出现了错误,因为当m=3时,即使n很小,结果也会很大,所以无法利用m=2时的结果递推,要怎么办呢?  将m=2的结果打印出来可以发现这是一个等差数列,通项为S(n) = 2*n + 3; 这有什么用呢? 我们可以发现,当 m=3时由递推式可以写成A(m,n) = A(2,A(m,n-1)) = 2*A(m,n-1) + 3; 所以只要知道了A(3,0),我们就能递推出所有m=3时的值了 . 细节

HDU 4914 Linear recursive sequence(矩阵乘法递推的优化)

题解见X姐的论文 矩阵乘法递推的优化,只是mark一下.. HDU 4914 Linear recursive sequence(矩阵乘法递推的优化)