Codeforces-1256-C. Platforms Jumping(贪心)

C. Platforms Jumping

There is a river of width n. The left bank of the river is cell 0 and the right bank is cell n+1 (more formally, the river can be represented as a sequence of n+2 cells numbered from 0 to n+1). There are also m wooden platforms on a river, the i-th platform has length ci (so the i-th platform takes ci consecutive cells of the river). It is guaranteed that the sum of lengths of platforms does not exceed n.

You are standing at 0 and want to reach n+1 somehow. If you are standing at the position x, you can jump to any position in the range [x+1;x+d]. However you don’t really like the water so you can jump only to such cells that belong to some wooden platform. For example, if d=1, you can jump only to the next position (if it belongs to the wooden platform). You can assume that cells 0 and n+1 belong to wooden platforms.

You want to know if it is possible to reach n+1 from 0 if you can move any platform to the left or to the right arbitrary number of times (possibly, zero) as long as they do not intersect each other (but two platforms can touch each other). It also means that you cannot change the relative order of platforms.

Note that you should move platforms until you start jumping (in other words, you first move the platforms and then start jumping).

For example, if n=7, m=3, d=2 and c=[1,2,1], then one of the ways to reach 8 from 0 is follow:

The first example: n=7.

Input

The first line of the input contains three integers n, m and d (1≤n,m,d≤1000,m≤n) — the width of the river, the number of platforms and the maximum distance of your jump, correspondingly.

The second line of the input contains m integers c1,c2,…,cm (1≤ci≤n,∑i=1mci≤n), where ci is the length of the i-th platform.

Output

If it is impossible to reach n+1 from 0, print NO in the first line. Otherwise, print YES in the first line and the array a of length n in the second line — the sequence of river cells (excluding cell 0 and cell n+1).

If the cell i does not belong to any platform, ai should be 0. Otherwise, it should be equal to the index of the platform (1-indexed, platforms are numbered from 1 to m in order of input) to which the cell i belongs.

Note that all ai equal to 1 should form a contiguous subsegment of the array a of length c1, all ai equal to 2 should form a contiguous subsegment of the array a of length c2, …, all ai equal to m should form a contiguous subsegment of the array a of length cm. The leftmost position of 2 in a should be greater than the rightmost position of 1, the leftmost position of 3 in a should be greater than the rightmost position of 2, …, the leftmost position of m in a should be greater than the rightmost position of m−1.

See example outputs for better understanding.

Examples

input

7 3 2
1 2 1

output

YES
0 1 0 2 2 0 3 

input

10 1 11
1

output

YES
0 0 0 0 0 0 0 0 0 1 

input

10 1 5
2

output

YES
0 0 0 0 1 1 0 0 0 0 

Note

Consider the first example: the answer is [0,1,0,2,2,0,3]. The sequence of jumps you perform is 0→2→4→5→7→8.

Consider the second example: it does not matter how to place the platform because you always can jump from 0 to 11.

Consider the third example: the answer is [0,0,0,0,1,1,0,0,0,0]. The sequence of jumps you perform is 0→5→6→11.

解题思路:

题意是给定一个长度的水沟,和m块木板,还有一次可以跳跃的距离。以及每块模板的长度。
首先可以考虑他每次可以跳1或者d的距离,那么他最多一次可以越过d-1个水格子,那么他可以跳过的总的水沟格数最大应该是d-1 乘以木板的个数+1。这个加上木板长度的总和,可以判断是否可以安全跳到对岸。
接下来是输出答案的问题,首先考虑把所有木板全部挨着放在右边,然后左边按照最大d-1的距离隔开,先计算出需要用多少块木板隔开,然后输出这些木板以及水沟,最后的剩下的木板全挨着排在右边,依次输出他们的编号就行。

AC代码:

#include <iostream>
#include <cstdio>
const int N = 1e6+10;
using namespace std;
typedef long long ll;

ll n,m,d;
ll a[N];
ll sum2[2];
ll sum[N] = {0};
ll sum1;

int main()
{
    cin>>m>>n>>d;
    sum1 = 0;
    for(int i = 0 ; i < n ; i ++)
    {
        cin>>a[i];
        sum[i] += a[i];
        sum1 += a[i]; // 木板总长
    }
    ll step = d-1;
    ll water = m-sum1;
    if (d == 1)
    {
        if(sum1 == m)
        {
            cout<<"YES"<<endl;
            for(int i = 1 ; i <= n  ; i ++)
            {
                for(int j = 0 ; j < a[i-1] ; j ++)
                    cout<<i<<" ";
            }
            cout<<endl;
        }
        else
            cout<<"NO"<<endl;
        return 0;
    }
    ll tmp = water/step;
    if((step)*(n+1) + sum1 >= m )
    {
        cout<<"YES"<<endl;
        for(int i = 1 ; i <= tmp ; i ++)
        {
            for(int j = 0 ; j < step ; j ++)
                cout<<'0'<<" ";
            for(int j = 0 ; j < a[i-1] ; j ++)
                cout<<i<<" ";
        }
        if(water%(step) != 0)
        {
            for(int i = 0 ; i < water-(water/(step))*(step) ; i ++)
                cout<<"0"<<" ";
        }
        for(int i = tmp ; i < n ; i ++)
        {
            for(int j = 0 ; j < a[i] ; j ++)
                cout<<i+1<<" ";
        }
        cout<<endl;
    }
    else
        cout<<"NO"<<endl;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值