ARC 100
C
原式$\sum{|a_i-(b+i)|}$可以转化为$\sum{|(a_i-i)-b|}$
$b_i=a_i-i$
即求$\sum{|b_i-b|}$,
D
先要想到切中间那刀。
方法一:piont to point
方法二:二分答案(ggg)
E
$i or j\leq k$可以转化为$i or j=k$和$i or j\leq k-1$
后一式子可以通过$k-1$转移
讨论$i or j=k$的情况
#include<bits/stdc++.h> using namespace std; const long long N=1<<19; long long a[N]; long long n,pp; struct re{ long long num; long long id; }x[5],dp[N][2]; long long maxer; short p[N]; bool cmp(re x,re y){return x.num<y.num;} int main() { freopen ("p.in","r",stdin); freopen("p.out","w",stdout); ios::sync_with_stdio(0); cin>>n; pp=(1<<n)-1; for(long long i=0;i<=pp;i++){ long long c; cin>>a[i]; dp[i][0].num=a[i]; dp[i][0].id=i; dp[i][1].id=-100; } for(long long i=1;i<pp;i++){ for(long long j=0;j<n;j++)if((1<<j)&i){ long long k=(1<<j)^i; x[1]=dp[k][0]; x[2]=dp[k][1]; x[3].num=a[i]; x[4].num=a[1<<j]; x[3].id=i; x[4].id=1<<j; sort(x+1,x+1+4,cmp); int az=0,s; for(int l=4;l>=1;l--) if(x[l].num>dp[i][0].num){ az=1; re ax=dp[i][0]; dp[i][0]=x[l]; x[l]=ax; break;} for(int l=4;l>=1;l--) if(x[l].num>dp[i][1].num&&dp[i][0].id!=x[l].id) {dp[i][1]=x[l];} } maxer=max(maxer,dp[i][1].num+dp[i][0].num); cout<<maxer<<endl; } long long i=pp; for(long long j=0;j<n;j++)if((1<<j)&i){ long long k=(1<<j)^i; x[1]=dp[k][0]; x[2]=dp[k][1]; x[3].num=a[i]; x[4].num=a[1<<j]; x[3].id=i; x[4].id=1<<j; sort(x+1,x+1+4,cmp); int az=0,s; for(int l=4;l>=1;l--) if(x[l].num>dp[i][0].num){ az=1; re ax=dp[i][0]; dp[i][0]=x[l]; x[l]=ax; break;} for(int l=4;l>=1;l--) if(x[l].num>dp[i][1].num&&dp[i][0].id!=x[l].id) {dp[i][1]=x[l];} } maxer=max(maxer,dp[i][1].num+dp[i][0].num); cout<<maxer<<endl; return 0; }
戒骄戒躁