Sugoroku(单调队列优化DP)

题目描述
Takahashi is playing a board game called Sugoroku.
On the board, there are N+1 squares numbered 0 to N. Takahashi starts at Square 0, and he has to stop exactly at Square N to win the game.
The game uses a roulette with the M numbers from 1 to M. In each turn, Takahashi spins the roulette. If the number x comes up when he is at Square s, he moves to Square s+x. If this makes him go beyond Square N, he loses the game.
Additionally, some of the squares are Game Over Squares. He also loses the game if he stops at one of those squares. You are given a string S of length N+1, representing which squares are Game Over Squares. For each i (0≤i≤N), Square i is a Game Over Square if S[i]=1 and not if S[i]=0.
Find the sequence of numbers coming up in the roulette in which Takahashi can win the game in the fewest number of turns possible. If there are multiple such sequences, find the lexicographically smallest such sequence. If Takahashi cannot win the game, print −1.

Constraints
·1≤N≤105
·1≤M≤105
·|S|=N+1
·S consists of 0 and 1.
·S[0]= 0
·S[N]= 0

输入
Input is given from Standard Input in the following format:

N M
S

输出
If Takahashi can win the game, print the lexicographically smallest sequence among the shortest sequences of numbers coming up in the roulette in which Takahashi can win the game, with spaces in between.
If Takahashi cannot win the game, print −1.

样例输入
【样例1】
9 3
0001000100
【样例2】
5 4
011110
【样例3】
6 6
0101010

样例输出
【样例1】
1 3 2 3
【样例2】
-1
【样例3】
6

提示
样例1解释
If the numbers 1, 3, 2, 3 come up in this order, Takahashi can reach Square 9 via Square 1, 4, and 6. He cannot reach Square 9 in three or fewer turns, and this is the lexicographically smallest sequence in which he reaches Square 9 in four turns.

思路
由题意可直接想到dp的解法,由于N<105所以直接DP时间复杂度为O(n2),因此使用单调队列优化DP

代码实现

#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=2e5+5;
const int M=1e6+5;
const int INF=0x3f3f3f3f;
const ll LINF=1e17;
const ull sed=31;
const ll mod=1e9+7;
const double eps=1e-8;
const double PI=3.14159265358979;
typedef pair<int,int>P;
typedef pair<double,double>Pd;

int n,m,dp[N],pre[N];
deque<P>q;
char s[N];

void output(int x)
{
    if(!pre[x])
    {
        printf("%d",x);
        return ;
    }
    output(pre[x]);
    printf(" %d",x-pre[x]);
}
int main()
{
    scanf("%d%d",&n,&m);
    scanf("%s",s);
    for(int i=1;i<=n;i++) dp[i]=INF;
    q.push_back(P(dp[0],0));
    for(int i=1;i<=n;i++)
    {
        while(!q.empty() && i-q.front().second>m) q.pop_front();
        if(s[i]=='1') continue;
        if(!q.empty())
        {
            dp[i]=q.front().first+1;
            pre[i]=q.front().second;
        }
        while(!q.empty() && q.back().first>dp[i]) q.pop_back();
        if(dp[i]!=INF) q.push_back(P(dp[i],i));
    }
    if(dp[n]==INF) printf("-1");
    else output(n);
    puts("");
    return 0;
}

发布了235 篇原创文章 · 获赞 13 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_43935894/article/details/104911632
今日推荐