[20200716NOIP提高组模拟T2]平方数游戏

题目大意:

  求序列${a_{i}}$,使得$|\sum_{i=1}^{n}a_{i}\cdot i^{2}|_{min}$,其中$a_{i}\in{1,-1}$.

解题思路:

 由打表可以看出,$n\leq 5$时,答案为特殊情况,打表解决;$n\geq 6$时,答案呈10011001......排布,所以其中必有一定规律.

 又由于$n^{2}-(n+1)^{2}-(n+2)^{2}+(n+3)^{2}=-4$可以看出,我们只需枚举[6,13]内的数,然后往后补若干个{1,-1,-1,1,-1,1,1,-1}即可保持答案最小.

code:

 

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
#define mod 19900907
#define R register
#define next exnt
#define debug puts("mlg")
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
inline ll read();
inline void write(ll x);
inline void writesp(ll x);
inline void writeln(ll x);
ll n;
ll ans=1234561370120;
ll a[55555],b[55555];
inline void dfs(ll x){
    if(x==n+1){
        ll sum=0;
        for(R ll i=1;i<=n;i++){
            sum+=a[i]*i*i;
        }
        if(abs(sum)<ans){
            ans=abs(sum);
            for(R ll i=1;i<=n;i++) b[i]=a[i];
        }
        return;
    }
    a[x]=1;
    dfs(x+1);
    a[x]=-1;
    dfs(x+1);
}
ll Ans;
int main(){
    freopen("five.in","r",stdin);
    freopen("five.out","w",stdout);
    n=read();
    if(n==1)writeln(1),writesp(1);
    if(n==2)writeln(3),writesp(1),writesp(-1);
    if(n==3)writeln(4),writesp(1),writesp(1),writesp(-1);
    if(n==4)writeln(2),writesp(1),writesp(1),writesp(1),writesp(-1);
    if(n==5)writeln(3),writesp(1),writesp(-1),writesp(1),writesp(1),writeln(-1);
    if(n<=5) return 0;
    while(n>13) n-=8,Ans++;
    dfs(1);
    writeln(ans);
    for(R ll i=1;i<=n;i++) writesp(b[i]);
    for(R ll i=1;i<=Ans;i++) writesp(1),writesp(-1),writesp(-1),writesp(1),writesp(-1),writesp(1),writesp(1),writesp(-1);
}
inline ll read(){
    ll x=0,t=1;char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-') t=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*t;
}
inline void write(ll x){
    if(x<0){putchar('-');x=-x;}
    if(x<=9){putchar(x+'0');return;}
    write(x/10);putchar(x%10+'0');
}
inline void writesp(ll x){
    write(x);putchar(' ');
}
inline void writeln(ll x){
    write(x);putchar('\n');
}

 

posted @ 2020-07-16 19:48  月落乌啼算钱  阅读(99)  评论(0编辑  收藏  举报