美文网首页
Educational Codeforces Round 69

Educational Codeforces Round 69

作者: 林即中 | 来源:发表于2019-07-28 21:31 被阅读0次

A. DIY Wooden Ladder

先找出数组中最大的两个元素a和b,b是第二大的数。答案是min(b-1,n-2)

#include <iostream>
#include <cstdio>
using namespace std;
const int N = 100010;
int arr[N];
#define min(a,b) ((a)<(b)?(a):(b))
int main()
{
#ifdef CODEBLOCKS
    freopen("in.txt","r",stdin);
#endif
    int t;
    cin>>t;
    for(int ti=0; ti<t; ti++)
    {
        int n;
        cin>>n;
        int a=-1,b=-1;
        for(int i=0; i<n; i++)
        {
            cin>>arr[i];
            if(arr[i]>a)
            {
                b=a;
                a= arr[i];
            }
            else if(arr[i]>b)
            {
                b=arr[i];
            }
        }
        int ret = min(b-1,n-2);
        if(ret<0)
            ret = 0;
        cout<<ret<<endl;
    }
    return 0;
}

B. Pillars

首先找出最大的元素a_i,目标是将所有盘子移到i处。如果对于j<k<i,a_j>a_k,那么盘子j将无法移到柱子i。同理如果j>k>i,a_j>a_k也会导致所有盘子无法移到i处。找到最大元素a_i后向左向右遍历一遍即可。

#include <iostream>
#include <cstdio>
using namespace std;
const int N = 2*100010;
int n;
int arr[N];
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
bool solve()
{
    int ti = -1;
    int t = -1;
    for(int i=0;i<n;i++)
    {
        if(arr[i] > t)
        {
            t = arr[i];
            ti = i;
        }
    }
    int a = t;
    for(int i=ti-1;i>=0;i--)
    {
        int x = arr[i];
        if(x>=a)
        {
            return false;
        }
        a = min(x, a);
    }
    a = t;
    for(int i=ti+1;i<n;i++)
    {
        int x = arr[i];
        if(x>=a)
        {
            return false;
        }
        a=min(x,a);
    }
    return true;
 
}
int main()
{
    #ifdef CODEBLOCKS
    freopen("in.txt","r",stdin);
    #endif
    while(cin>>n)
    {
 
        for(int i=0;i<n;i++)
        {
            cin>>arr[i];
        }
 
        if(solve())
        {
            cout<<"YES"<<endl;
        }
        else
        {
            cout<<"NO"<<endl;
        }
    }
 
    return 0;
}

C. Array Splitting

对于分好后的第x个连续子数组a_i,a_{i+1},a_{i+2},...,a_{i+j}max(x) = a_{i+j}-a_i = a_{i+j} - a_{i+j-1} + a_{i+j-1} - a_{i+j-2}+...+a_{i+2}-a_{i+1}+a_{i+1}-a_i

当k=1时,所求答案为\Sigma_{x=1}^{n-1}a_{x+1}-a_{x}

当k=2时,假设分区是1~i,i+1~n,则答案是\Sigma_{x=1}^{i-1}(a_{x+1}-a_{x}) + \Sigma_{x=i+1}^{n-1}(a_{x+1}-a_{x}) = \Sigma_{x=1}^{n-1}(a_{x+1}-a_{x}) - (a_{i+1} - a_{i})

以此类推,答案应该为\Sigma_{x=1}^{n-1}(a_{x+1}-a_{x})减去k-1个最大的(a_{i+1} - a_{i})

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 3*100010;
int arr[N];
int q[N];
int n,k;
 
#define min(a,b) ((a)<(b)?(a):(b))
int main()
{
#ifdef CODEBLOCKS
    freopen("in.txt","r",stdin);
#endif
    while(cin>>n>>k)
    {
        for(int i=0;i<n;i++)
        {
            cin>>arr[i];
            if(i>0)
            {
                q[i-1]=arr[i]-arr[i-1];
            }
        }
        sort(q,q+n-1);
        long long sum = 0;
        for(int i=0;i<n-k;i++)
        {
            sum+=q[i];
        }
        cout<<sum<<endl;
    }
    return 0;
}

D. Yet Another Subarray Problem

best[i]为子数组以第i个元素结尾所能得到的最佳答案。
分两种情况。考虑j>i-m,j~i的子数组的花费为\Sigma_{t=j}^i a_t - k。而对于所有j<=i-m时,j~i的子数组最小花费为best[i-m]+ \Sigma_{t=i-m+1}^i a_t - k。best[i]取两者答案的最小值。算法时间复杂度为O(nm)

#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;
const int N = 3*100010;
int arr[N];
long long best[N];
int n,m,k;
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
int main()
{
#ifdef CODEBLOCKS
    freopen("in.txt","r",stdin);
#endif
    while(cin>>n>>m>>k)
    {
        long long ret = 0;
        for(int i=0;i<n;i++)
        {
            cin>>arr[i];
            best[i] = max(0, arr[i]-k);
            ret = max(ret,best[i]);
        }

        for(int i=1;i<n;i++)
        {
            long long t = 0;
            for(int j=0;j<m &&i-j>= 0;j++)
            {
                t += arr[i-j];
                best[i] = max(best[i], t-k);
            }
            if(i>=m)
            {
                best[i] = max(best[i], t-k+best[i-m]);
            }
            ret = max(best[i], ret);
        }
        cout<<ret<<endl;
    }
    return 0;
}

E. Culture

对所有数据以(in_i, out_i)排序。
dp[i] = (extraspace_i, count_i),其中extraspace_i表示以i-n所有套娃构造所能组成的最小extraspace,count_i表示以i-n所有套娃构造所能组成的满足条件的套娃数目。

倒序遍历数据,对于(in_i, out_i),找到恰好大于(out_i, 0)的位置pos,那么对于套娃i应该能装在pos-n中的某些套娃中,其extraspace应该等于dp[pos].extraspace + out_i - in_i

那么对于dp[i]的计算,分三种情况。
a. extraspace > dp[i+1].extraspace时,说明第i个套娃无法与其他套娃构造成最小extraspace,不纳入计算,dp[i] = dp[i+1]

b. extraspace == dp[i+1].extraspace时,第i个套娃应该可以构造出dp[pos].count个满足条件的套娃。dp[i].extraspace = extraspace\\ dp[i].count = dp[pos].count + dp[i+1].count

c. extraspace < dp[i+1].extraspace时,dp[i].extraspace = extraspace\\ dp[i].count = dp[pos].count

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <map>
using namespace std;
int n;
const int N = 2*1e5+10;
pair<int, int> p[N];
pair<int, long long> dp[N];
const int mod = 1e9+7;
int main()
{
#ifdef CODEBLOCKS
    freopen("in.txt", "r", stdin);
#endif // CODEBLOCKS
    while(cin>>n)
    {
        int min_out = 0x7fffffff;
        for(int i=0;i<n;i++)
        {
            int a,b;
            cin>>a>>b;
            p[i] = make_pair(b,a);
        }
        sort(p, p+n);
        for(int i=n-1;i>=0;i--)
        {
            int in = p[i].first;
            int out = p[i].second;
            auto iter = lower_bound(p, p+n, make_pair(out,0));
            int space, cnt;
            if((iter-p) == n)
            {
                space = in;
                cnt = 1;
            }
            else
            {
                space = dp[iter - p].first - out + in;
                cnt = dp[iter-p].second;
            }
 
            if(i<n-1)
            {
                if(space > dp[i+1].first)
                {
                    space = dp[i+1].first;
                    cnt = dp[i+1].second;
                }
                else if(space == dp[i+1].first)
                {
                    cnt = (cnt + dp[i+1].second)%mod;
                }
            }
            dp[i] = make_pair(space, cnt);
        }
        cout<<dp[0].second<<endl;
    }
    return 0;
}

相关文章

网友评论

      本文标题:Educational Codeforces Round 69

      本文链接:https://www.haomeiwen.com/subject/ejbprctx.html