CF1277C As Simple as One and Two(枚举+剪枝)

题意:

给定一个序列,请你对他重新排列使得他有最长的Fib前缀。

题解:

由斐波那契数列的性质可得,一个序列当确定了前两个数时,这个序列的前缀长度就已经确定了。

暴力枚举,把全0的情况剪掉就行。

/*
 *author: zlc
 *zucc_acm_lab
 *just do it
 */
#include<bits/stdc++.h> 
using namespace std;
typedef long long ll;
const double pi=acos(-1.0);
const double eps=1e-6;
const int mod=1e9+7;
const int inf=1e9;
const int maxn=2e5+100;
inline ll read () {ll x=0;ll f=1;char ch=getchar();while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}while (ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}return x*f;}
//inline int read () {int x=0;int f=1;char ch=getchar();while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}while (ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}return x*f;}
ll qpow (ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
ll n,k,x;
ll a[maxn];
struct qnode {
    ll v;
    bool operator < (const qnode &r) const {return abs(a[v])>abs(a[r.v]);}
    qnode (ll vv) {v=vv;}
};
int main () {
    n=read();k=read();x=read();
    for (int i=1;i<=n;i++) a[i]=read();
    int cnt=0;//负数的数量
    for (int i=1;i<=n;i++) if (a[i]<0) cnt++;
    priority_queue<qnode> q;
    for (int i=1;i<=n;i++) q.push(qnode(i));
    int tot=0;
    int f=0;
    while (q.size()&&tot<k) {
        qnode tt=q.top();
        q.pop();
        if (a[tt.v]<0) {
            if (cnt%2==0) {
                a[tt.v]+=x;
                if (a[tt.v]>=0) cnt--;     
            }
            else
                a[tt.v]-=x;
        }
        else {
            if (cnt%2==0) {
                a[tt.v]-=x;
                if (a[tt.v]<0) cnt++;    
            }
            else
                a[tt.v]+=x;
        }
        q.push(tt.v);
        tot++;
    }
    for (int i=1;i<=n;i++) printf("%lld ",a[i]);   
}

 

posted @ 2020-09-10 18:01  zlc0405  阅读(128)  评论(0编辑  收藏  举报