首页 > 其他 > 详细

CodeForces 1305E Kuroni and the Score Distribution 题解

时间:2020-03-05 10:38:44      阅读:64      评论:0      收藏:0      [点我收藏+]

CF1305E题目链接

\(dp\) 题写多了,写道构造题

首先不要被 \(10^9\) 吓到。可以猜出 \(1,2,3,...,n\) 这样的序列能使对数最大。

我们看看每个位置的贡献:

\[0,0,1,1,2,2,3,3,4,4...\]

这样可以暴力算出最大对数,如果还小于 \(k\) 就只能无解。

否则可以猜出一定有答案。

考虑这样一种构造:每次把整个序列增加 \(1\) ,直到不能再加,然后更改最后一个数

正确性?

\(n=10\) 为例,贡献的序列是这样的:

\[0,0,1,1,2,2,3,3,4,4\]
\[0,0,0,1,1,2,2,3,3,4;\Delta = 4\]
\[0,0,0,0,1,1,2,2,3,3;\Delta = 4\]

也就是每次整体右移一位,把最右边的扔掉,总数的变化值等于最右边的数的贡献

这样 \(\Delta\) 一定不大于 \(val_{last} + 1\)\(val_{last}\) 为移动后最后一位的贡献,即所以 \(k\) 都能达到

最后考虑实现。设序列为\(a\),则最后一个数为\(a_{n}\)

整体增加完了之后,自然的想法是直接把最后一位增加 \(2 \times rest\)\(rest\) 为当前对数与 \(k\) 的差值,因为观察能够得到,\(a_{n}\) 每增加 \(2\) ,贡献就会变化 \(1\) 。但是,我们发现直接增加是错误的,因为增加\(2\)时,贡献可能减少 \(1\) ,也可能增加 \(1\)

当时被这个卡了一会

解决方法很简单。 \(a_{n}\) 是原来前面的两个数的和,我们要把它变成后面的两个数的和。

\(3,4,5,6,7,8\)

在这个序列中,\(8=3+5\) ,但是增加 \(2\)\(10=3+7\) ,贡献反而变大了。可以想办法把它变成 \(5+7\),这样贡献不变,但后面改变时贡献一定减少。

观察发现\(a_n\) 改成 \(2 (a_1 + a_{n-1}) - a_n\) 就行了

这题是不是比 D 简单啊...还是我前天太瞌睡了...

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mit map<int,int>::iterator
#define sit set<int>::iterator
#define itrm(g,x) for(mit g=x.begin();g!=x.end();g++)
#define itrs(g,x) for(sit g=x.begin();g!=x.end();g++)
#define ltype int
#define rep(i,j,k) for(ltype(i)=(j);(i)<=(k);(i)++)
#define rap(i,j,k) for(ltype(i)=(j);(i)<(k);(i)++)
#define per(i,j,k) for(ltype(i)=(j);(i)>=(k);(i)--)
#define pii pair<int,int>
#define fi first
#define se second
#define mpr make_pair
#define pb push_back
#define fastio ios::sync_with_stdio(false)
const int inf=0x3f3f3f3f,mod=1000000007;
const double pi=3.1415926535897932,eps=1e-6;
int n,m,mx,a[5005];
int main()
{
    scanf("%d%d",&n,&m);
    rep(i,1,n) mx += (i-1) / 2;
    if(mx < m) {puts("-1");return 0;}
    rep(i,1,n) a[i] = i;
    rep(i,1,n - 2) {
        int nxt = (n - i)/2;//直接计算整体增加1后总对数的变化值
        if(mx - nxt >= m) {
            mx -= nxt;
            rep(j,1,n) a[j]++;
        }else break;
    }
    a[n] = (a[1] + a[n-1]) * 2 - a[n];
    a[n] += (mx - m) * 2;
    rep(i,1,n) printf("%d ",a[i]);
    return 0;
}

CodeForces 1305E Kuroni and the Score Distribution 题解

原文:https://www.cnblogs.com/yz-beacon-cwk/p/12418265.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!