CF598 div3 C.Platforms Jumping (贪心)

CF598 div3 C.Platforms Jumping (贪心)

在这里插入图片描述
在这里插入图片描述
是的,没错,这套题前四题都是greedy
题目意思:就是有一条长度为n的河流,人再0点,要抵达n+1点,度过这条河流。提供了m块板,人最远跳d个长度。第一行给了n,m,d,第二行给了m块木板各自的长度。在人起跳之前安排好木板放置的位置,然后问你人是否能过河,能的话给出木板排放的样子。就是如果该段没有放板子,那么就是0;放了就标上板的编号。规定每块板子都要放上去,并且他们不能有重叠的部分。
解题思路:很容易发现,人能否过河在给定条件下就已经能判断了。有m块板子,他们的总长为sum的话,那么空的区域长度就是n-sum。我每次能跳最远的空格是d-1,能跳空格次数最多是m+1次,那么我跳过的空格最大能到(m+1)*(d-1)个,如果这个数小于n-sum的话,就输出NO。否则就是可以的。
可以的情况下,我们再来安排木板的位置。那么我每次跳最好跳多少呢。如果用space记录当前情况下河上还有多少个空格要跳过的话,我的做法是求一个space和d-1的最小值,我前期先把空格跳掉,后期实在不行把木板相邻放置,然后每跳一次更新一下space的大小就可以了。
代码如下:

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int panel[1000+10];
int river[1000+10];
int n,m,d;
int main()
{
    
    
   cin>>n>>m>>d;
   int sum=0;
   for(int i=1;i<=m;++i){
    
    
    scanf("%d",&panel[i]);
    sum+=panel[i];
   }
   int space=n-sum;
   if((m+1)*(d-1)<space){
    
    
    printf("NO\n");
    return 0;
   }
   int current=0;
   for(int i=1;i<=m;++i){
    
    
    int s=min(d-1,space);
    for(int j=current+s+1;j<=current+s+panel[i];++j)
        river[j]=i;
    current=current+s+panel[i];
    space-=s;
   }
   printf("YES\n");
   for(int i=1;i<=n;++i) printf("%d ",river[i]);
   printf("\n");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43329358/article/details/103016804
今日推荐