Vijos 1002 (Dynamic Programming)

describe

There is a single-plank bridge over the river, and a frog wants to jump from one side of the river to the other along the single-plank bridge. There are some stones on the bridge that frogs hate to step on. Since the length of the bridge and the distance that the frog jumps at a time are both positive integers, we can regard the points on the single-plank bridge that the frog may reach as a series of whole points on the number line: 0, 1, ..., L (where L is the length of the bridge ). The point with coordinate 0 represents the start point of the bridge, and the point with coordinate L represents the end point of the bridge. The frog starts from the beginning of the bridge and keeps jumping towards the end. The distance of a jump is any positive integer between S and T (including S, T). When the frog jumps to or jumps over the point whose coordinate is L, even if the frog has jumped out of the single-plank bridge.

The title gives the length L of the single-plank bridge, the distance range S and T of the frog jumping, and the position of the stones on the bridge. Your task is to determine the minimum number of stones the frog needs to step on in order to cross the river.

For 30% of the data, L <= 10000;
for all the data, L <= 10^9.

Format

input format

The first line of input has a positive integer L (1 <= L <= 10^9), which represents the length of the single-plank bridge. The second line has three positive integers S, T, and M, which represent the minimum distance, the maximum distance, and the number of stones on the bridge, respectively, where 1 <= S <= T <= 10, 1 <= M < = 100. The third line has M different positive integers representing the positions of the M stones on the number line (the data ensures that there are no stones at the start and end points of the bridge). All adjacent integers are separated by a space.

output format

The output consists only of an integer representing the minimum number of pebbles that frogger needs to step on.

Example 1

Sample input 1

10
2 3 5
2 3 5 6 7

Sample output 1

2


1. First, you must know that the positions of the stones are not given in order, so you need to sort the array of stone positions.

2. Next, analyze the program itself:

(1) First analyze 30% of the data:

        When the frog jumps to position n, the number of stones it steps on is only related to the number of stones in its previous step and this position. Because the length of each jump of the frog is ST, when the frog is adjusted to n, the minimum number of stones it steps on is

f(n)=min{f(n-T),f(n-T+1)······f(n-S)}+b(n)

Among them, f(n) is the minimum value of the stones stepped on when the position is n, and when b(n) is 1, it means that there are stones here.

Because some positions are impossible to step on, initialize f(n) to -1 and f(0)=0.

(2) When the value of L reaches 10^9, we cannot define such a large array to represent every position of the entire journey, so further optimization is required.

Because the value of L can reach 10^9, and the number of stones is only 100 at most, and the number is so different, there must be a large distance between several stones. What will this lead to? We all know that between two adjacent stones, the value of each f(n) is either -1 or the same, and when the distance reaches a certain level, every position after that may be stepped on, And the value of f(n) is equal. Since 1<=S<=T<=10, this value is 90.

That is, if the distance between two stones is greater than 90, every position after the first stone 90 may be stepped on, and f(n) is equal.

There is a special case: when S=T, the solution is particularly simple, just judge whether each stone can make S.


#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;


intmain()
{
    long int L; // length of bridge
    int S,T,M; //step size, number of stones
    long int stone[102]; //Stone position
    int f[10000];  //f(n)
    int b[10000]; //Whether there are stones in this position
    int MinStone;
    cin>>L;
    cin>>S>>T>>M;
    for(int i=0;i<M;i++)
        cin>>stone[i];
    if(S!=T)
    {
        sort(stone,stone+M); //sort the stone positions
        stone[M]=L;
        //Optimize the length and delete useless positions
        if(stone[0]>90)
        {
            long int k=stone[0]-90;
            for(int i=0;i<=M;i++)
                stone[i]-=k;
        }
        for(int i=1;i<=M;i++)
            if(stone[i]-stone[i-1]>90)
            {
                long int k=stone[i]-stone[i-1]-90;
                for(int j=i;j<=M;j++)
                    stone[j]-=k;
            }
        memset(f,-1,sizeof(f));
        memset(b,0,sizeof(b));
        for(int i=0;i<M;i++)
            b[stone[i]]=1;
        f[0]=0;
        for(int i=S;i<stone[M]+T;i++)
        {
            MinStone=101;
            for(int j=i-T;j<=i-S;j++)
                if(j>=0&&f[j]!=-1&&MinStone>f[j])
                    MinStone=f[j];
            if(MinStone!=101)
                f[i]=MinStone+b[i];
        }
        MinStone=101;
        for(int i=stone[M];i<stone[M]+T;i++)
            if(MinStone>f[i]&&f[i]!=-1)
                MinStone=f[i];
    }
    else
    {
        MinStone=0;
        for(int i=0;i<M;i++)
            if(stone[i]%S==0)
                MinStone++;
    }
    cout<<MinStone;
    return 0;
}
Reference: https://blog.csdn.net/liuhuiyi/article/details/8202453



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324588275&siteId=291194637