codeforces891B Gluttony题解

第一次做构造题..orz…
.一开始以为是状压DP啥的想了半天发现一脸不可做
于是生无可恋的洗洗睡了
早晨看到题解和AC代码感觉只有一个:蛤?


惯例说说题意。
一个由 n 个元素构成的数列T(满足互异性),假定 T T 的一个排列。
如果满足MS,其中 S 表示1n构成的集合,有 TMiTMi 恒成立,则 T 为所求的一个集合。
现在给你这样的 T ,输出可能的一个T。如果不存在输出 1


做法很玄妙。
首先,我们对 T 进行排序,构成T1
然后,用题解的话说,”shift it by one”,也就是整个移动一下。
怎么移动呢?按照排序后的位置+1重新排一下,有点类似莫队的离散化过程。
玄学题,先放代码吧。证明之后再说。

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int n;
struct node{
    int x, pos;
}m[25];
int ansT[25];
bool cmp(node a, node b) {
    return a.x < b.x;
}
int main() {
    cin>>n;
    for(int i = 1; i <= n; ++i) cin>>m[i].x, m[i].pos = i;
    sort(m + 1, m + n + 1, cmp);
    ansT[m[1].pos] = m[n].x;
    for(int i = 2; i <= n; ++i) ansT[m[i].pos] = m[i - 1].x;
    for(int i = 1; i <= n; ++i) cout<<ansT[i]<<" ";
    return 0;
} 

接下来就是这种做法正确性证明了。
一开始我也百思不得其解,然后看了讨论,顿悟:
这个步骤相当于将第 k 大交换到第k1大的位置上。
因此任何数列都可以等效这样一个数列: a:ai=i ,对这一数列的操作相当于整个向左拖动并把最小的那个扔到最后去,形成数列 b
考虑第一个元素,
如果a1M,那么 bi<ai(iM) 是恒成立的,因为都变小了。
否则,令 M=Ma ,那么 bi<ai(iM) ,总和不变,所以 bi>ai(iM) 恒成立。
综上所述, b 是符合条件的a的一种变换。
因此该做法是正确的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值