题目大意:
求序列${a_{i}}$,使得$|sum_{i=1}^{n}a_{i}cdot i^{2}|_{min}$,其中$a_{i}in{1,-1}$.
解题思路:
由打表可以看出,$nleq 5$时,答案为特殊情况,打表解决;$ngeq 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(' '); }