沙雕场,ABC代码一个比一个短,D分治稍稍变了一下型半天没调出来(雾)……
快乐掉分~快乐掉发~
画一下就出来了不解释。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
int main()
{
int T;
cin>>T;
while(T--){
int n;
cin>>n;
int a[maxn];
for(int i=1;i<=n;i++){
cin>>a[i];
}
sort(a+1,a+1+n);
int h=a[n-1];
int m=min(h-1,n-2);
cout<<m<<endl;
}
return 0;
}
看看有没有除了端点的极小值。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 3e5+10;
int a[maxn];
int main()
{
int flag=1;
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=2;i<n;i++){
if(a[i]<=a[i+1]&&a[i]<=a[i-1]){
flag=0;
break;
}
}
if(flag==0){
cout<<"NO"<<endl;
}
else{
cout<<"YES"<<endl;
}
}
区间的花费可加。【1,3】+【3,5】=【1,5】
随便做就好了
不需要管它具体是怎么划分的。
每次只需要找花费最小的那个。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 4e5+10;
ll a[maxn];
bool vis[maxn];
int dp[maxn];
int main()
{
int n,k;
cin>>n>>k;
for(int i=1;i<=n;i++){
cin>>a[i];
}
if(k>=n){
cout<<0<<endl;
return 0;
}
priority_queue<ll,vector<ll>, greater<ll> > q;
for(int i=2;i<=k;i++){
q.push(a[i]-a[i-1]);
}
ll sum=0;
for(int i=k+1;i<=n;i++){
q.push(a[i]-a[i-1]);
sum+=q.top();
q.pop();
}
cout<<sum<<endl;
}
D - Yet Another Subarray Problem
最大连续区间和 的变形
当初学的时候两种方法,dp&分治
我用的分治。
因为它的代价与长度/m有关。
而m<=10
很容易想到与它的余数有关。
分治思想,你要左边最大+右边最大。
但这样合并的时候有可能多算了一个K
那么就可以按余数划分最大值。
很显然:
若 L: len(L)/m = a……b 则 -k*(a+1)
R: len(R)/m = c……d 则 -k*(b+1)
若 b+d<=m len(L+R) 花费 (a+b+1)
b+d> m len(L+R) 花费 (a+b+2)
最后对maxL和maxR全连接就好啦~
当时很懵逼所以代码很丑……
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 3e5+10;
ll a[maxn];
ll n,m,k;
ll maxsum(ll *A ,ll x ,ll y)
{
if(y-x==1) return A[x]-k;
ll mid=x+(y-x)/2;
ll maxs=max(maxsum(A,x,mid),maxsum(A,mid,y));
//cout<<"x "<<x<<" y "<<y<<endl;
ll v=0;
ll LL[11],RR[11];
for(int i=0; i<11; i++)
{
LL[i]=-k;
RR[i]=-k;
}
LL[1]=A[mid-1]-k;
//cout<<"mid="<<mid<<endl;
for(int i=mid-1; i>=x; i--)
{
v+=a[i];
ll nv=v-k*((mid-i)/m);
if((mid-i)%m!=0)
{
nv-=k;
}
//cout<<v<<' '<<nv<<endl;
LL[(mid-i)%m]=max(LL[(mid-i)%m],nv);
//cout<<"LL"<<(mid-i)%m<<" : "<<LL[(mid-i)%m]<<endl;
}
v=0;
RR[1]=A[mid]-k;
for(int i=mid; i<y; i++)
{
v+=a[i];
ll nv=v-k*((i-mid+1)/m);
if((i-mid+1)%m!=0)
{
nv-=k;
}
RR[(i-mid+1)%m]=max(RR[(i-mid+1)%m],nv);
//cout<<"RR"<<(i-mid+1)%m<<" : "<<RR[(i-mid+1)%m]<<endl;
}
for(int i = 0; i <=min(m,mid-x); i++)
{
for(int j=0; j<=min(m,y-mid); j++)
{
if(i+j<=m)
{
if(i==0||j==0)
{
maxs=max(maxs,LL[i]+RR[j]);
}
else
maxs=max(maxs,LL[i]+RR[j]+k);
}
else
{
maxs=max(maxs,LL[i]+RR[j]);
}
//cout<<i<<' '<<j<<' '<<LL[i]<<' '<<RR[j]<<' '<<maxs<<endl;
}
}
//cout<<"L="<<x<<" R="<<y<<" -> "<<maxs<<endl;
return maxs;
}
int main()
{
cin>>n>>m>>k;
for(int i=1; i<=n; i++)
{
cin>>a[i];
}
cout<<max(0ll,maxsum(a,1,n+1))<<endl;
}
不会……留坑