HDU 3455 Leap Frog (线性dp)

Leap Frog

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

Total Submission(s): 638    Accepted Submission(s): 224

Problem Description

Jack and Jill play a game called "Leap Frog" in which they alternate turns jumping over each other. Both Jack and Jill can jump a maximum horizontal distance of 10 units in any single jump. You are given
a list of valid positions x1,x2,…, xn where Jack or Jill may stand. Jill initially starts at position x1, Jack initially starts at position x2, and their goal is to reach position xn.Determine
the minimum number of jumps needed until either Jack or Jill reaches the goal. The two players are never allowed to stand at the same position at the same time, and for each jump, the player in the rear must hop over the player in the front.

Input

The input file will contain multiple test cases. Each test case will begin with a single line containing a single integer n (where 2 <= n <= 100000). The next line will contain a list of integers x1,x2,…,
xn where 0 <=x1,x2,…, xn<= 1000000. The end-of-fi le is denoted by a single line containing "0".

Output

For each input test case, print the minimum total number of jumps needed for both players such that either Jack or Jill reaches the destination, or -1 if neither can reach the destination.

Sample Input

6
3 5 9 12 15 17
6
3 5 9 12 30 40

Sample Output

3
-1

Source

2009 Stanford Local ACM Programming Contest

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3455

题目大意:n个站点在一条线上,位置为xi,两只青蛙,第一只开始在第一个站点,第二只开始在第二个站点,它们每次最多跳10个单位长度,且每次跳必须超过彼此(不能落在同一个站点上),求两蛙任意一个到达目的地即最后一个站点时跳跃的总次数的最小值

题目分析:这题做的特别纠结,dp[i][0],dp[i][1],分别表示两青蛙跳i次的最远距离,跳的时候要做以下判断:

1.当前青蛙能超过前面的青蛙

2.超过后能落到某个站点(注意这里还要注意超过终点的情况)

3.超过后该青蛙的后面一只青蛙也能够超过它且落在某个站点上

满足以上条件的情况下取最大值,可知若第一只先到且跳了i次,总次数为2*i-1,若第二只则为2*i

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int const INF = 0x3fffffff;
int const MAX = 100005;
int dp[MAX][2], x[MAX];
bool has[MAX * 10];

int main()
{
    int n;
    while(scanf("%d", &n) != EOF && n)
    {
        int ans = -1;
        bool flag = false;
        memset(has, false, sizeof(has));
        memset(dp, 0, sizeof(dp));
        for(int i = 0; i < n; i++)
        {
            scanf("%d", &x[i]);
            has[x[i]] = true;
        }
        if(n == 2)
        {
            printf("0\n");
            continue;
        }
        dp[0][0] = x[0];
        dp[0][1] = x[1];
        for(int i = 1; i < n; i++)
        {
            for(int j = 2; j <= 10; j++)
            {
                int d0 = dp[i - 1][0] + j;
                if((has[d0] || d0 >= x[n - 1]) && d0 > dp[i - 1][1])
                {
                    for(int k = 2; k <= 10; k++)
                    {
                        if(dp[i - 1][1] + k > d0 && (has[dp[i - 1][1] + k] || dp[i - 1][1] + k >= x[n - 1]))
                        {
                            dp[i][0] = max(dp[i][0], d0);
                            break;
                        }
                    }
                }
            }
             for(int j = 2; j <= 10; j++)
            {
                int d1 = dp[i - 1][1] + j;
                if((has[d1] || d1 >= x[n - 1]) && d1 > dp[i][0])
                {
                    for(int k = 2; k <= 10; k++)
                    {
                        if(dp[i][0] + k > d1 && (has[dp[i][0] + k] || dp[i][0] + k >= x[n - 1]))
                        {
                            dp[i][1] = max(dp[i][1], d1);
                            break;
                        }
                    }
                }

            }
        }
        for(int i = 1; i < n; i++)
        {
            if(dp[i][0] >= x[n - 1])
            {
                flag = true;
                printf("%d\n", 2 * i - 1);
                break;
            }
            if(dp[i][1] >= x[n - 1])
            {
                flag = true;
                printf("%d\n", 2 * i);
                break;
            }
        }
        if(!flag)
            printf("-1\n");
    }
}

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

时间: 2024-08-11 09:56:27

HDU 3455 Leap Frog (线性dp)的相关文章

HDU 3455 Leap Frog(线性DP)

Problem Description Jack and Jill play a game called "Leap Frog" in which they alternate turns jumping over each other. Both Jack and Jill can jump a maximum horizontal distance of 10 units in any single jump. You are given a list of valid posit

hdu 3455 Leap Frog(状压DP)

Problem Description Jack and Jill play a game called "Leap Frog" in which they alternate turns jumping over each other. Both Jack and Jill can jump a maximum horizontal distance of 10 units in any single jump. You are given a list of valid posit

hdu 3455 Leap Frog

Leap Frog                                                             Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 623    Accepted Submission(s): 219 Problem Description Jack and Jill play a

HDU 5074 Hatsune Miku (线性dp)

Hatsune Miku Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 654    Accepted Submission(s): 471 Problem Description Hatsune Miku is a popular virtual singer. It is very popular in both Japan

HDU 1421 搬寝室 (线性dp 贪心预处理)

搬寝室 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 20642    Accepted Submission(s): 7013 Problem Description 搬寝室是很累的,xhd深有体会.时间追述2006年7月9号,那天xhd迫于无奈要从27号楼搬到3号楼,因为10号要封楼了.看着寝室里的n件物品,xhd开始发呆,因为n

HDU 4455 Substrings(线性dp,很有意思)

题意:这个题给你n个数,然后有q组询问,无修改,每次询问一个长度x,问你所有长度为x的区间价值加和是多少,区间的价值的计算是这样定义的,一个区间的价值就等于这个区间中不同数字的个数 思路:看了题解虽然理解了,但感觉还是很难想啊,原本这个题卡在了怎么把n2的降维成n的,这个题目也算是很经典的一个套路吧,疯狂预处理,把所需要的信息不断转化,疯狂降维预处理,然后达到On递推,感觉对于dp[i]和dp[i-1]之间的关系,单点贡献的那一部分不怎么容易想到,而且想到了单点贡献,也想不到怎么预处理,QAQ

HDU 4293 Groups (线性dp)

OJ题目:click here~~ 题目分析:n个人分为若干组 , 每一个人描写叙述其所在的组前面的人数和后面的人数.求这n个描写叙述中,最多正确的个数. 设dp[ i ] 为前i个人的描写叙述中最多正确的个数,则dp[ n ] 为要求的.num[ i ][ j ]  保存说前面有i个人 , 后面有j个人的人数,显然num[ i ][ j ]不超过n - i - j; 转移方程dp[ i ] = max(dp[ i ] , dp[ j ]  + num[ j ][ n - i ])  ,详解见代

动态规划——线性dp

我们在解决一些线性区间上的最优化问题的时候,往往也能够利用到动态规划的思想,这种问题可以叫做线性dp.在这篇文章中,我们将讨论有关线性dp的一些问题. 在有关线性dp问题中,有着几个比较经典而基础的模型,例如最长上升子序列(LIS).最长公共子序列(LCS).最大子序列和等,那么首先我们从这几个经典的问题出发开始对线性dp的探索. 首先我们来看最长上升子序列问题. 这个问题基于这样一个背景,对于含有n个元素的集合S = {a1.a2.a3……an},对于S的一个子序列S‘ = {ai,aj,ak

uva 11584 Partitioning by Palindromes 线性dp

// uva 11584 Partitioning by Palindromes 线性dp // // 题目意思是将一个字符串划分成尽量少的回文串 // // f[i]表示前i个字符能化成最少的回文串的数目 // // f[i] = min(f[i],f[j-1] + 1(j到i是回文串)) // // 这道题还是挺简单的,继续练 #include <algorithm> #include <bitset> #include <cassert> #include <