CF 1197 (Educational Codeforces Round 69 )

沙雕场,ABC代码一个比一个短,D分治稍稍变了一下型半天没调出来(雾)……

快乐掉分~快乐掉发~

A - DIY Wooden Ladder

画一下就出来了不解释。

#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;
}

B - Pillars

看看有没有除了端点的极小值。

#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;
    }
 
}

C - Array Splitting

区间的花费可加。【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;
 
}

E - Culture Code

不会……留坑

发布了19 篇原创文章 · 获赞 3 · 访问量 1385

猜你喜欢

转载自blog.csdn.net/xuanhuangwendao/article/details/97008760