codeforces1157D N Problems During K Days

博客给出Codeforces上题目1157D的链接,提供非寻常思路的题解,指出对序列1,2,3,...,k同时加常数序列仍合法,可加⌊kn−2k(k+1)⌋,并将余数从后往前贪心放置,还提及会给出代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链接

https://codeforces.com/problemset/problem/1157/D

题解

非寻常思路
需要灵光一现的感觉
这个上限增的比较快
注意到一个这样的事实:对序列 1 , 2 , 3 , . . . , k 1,2,3,...,k 1,2,3,...,k同时加上一个常数,这个序列仍然合法
那我就同时加一个 ⌊ n − k ( k + 1 ) 2 k ⌋ \lfloor{\frac{n-\frac{k(k+1)}{2}}{k}}\rfloor kn2k(k+1)
然后把余数贪心地从后往前放就好了

代码

#include <bits/stdc++.h>
#define maxn 100010
using namespace std;
typedef long long ll;
ll N, res, k, ans[maxn];
bool check()
{
    ll i;
    for(i=1;i<k;i++)if(ans[i+1]<=ans[i] or ans[i+1]>=2*ans[i])return false;
    return true;
}
int main()
{
    ll i;
    cin>>N>>k;
    res=N;
    for(i=1;i<=k;i++)
    {
        ans[i]=i;
        res-=i;
    }
    if(res<0)
    {
        printf("NO");
        return 0;
    }
    auto tmp=res/k;
    for(i=1;i<=k;i++)ans[i]+=tmp, res-=tmp;
    for(i=k;i>=2;i--)
    {
        auto t=min(res,ans[i-1]*2-ans[i]);
        ans[i]+=t;
        res-=t;
    }
    if(res==0)
    {
        printf("YES\n");
        for(i=1;i<=k;i++)printf("%lld ",ans[i]);
    }
    else
    {
        printf("NO\n");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值