Educational Codeforces Round 93 (Rated for Div. 2) (ABCD)

A. Bad Triangle

题意:

给你一个升序序列。

是否存在一组triple(三元组),不能成为三角形。

思路:

取最小的两条边,和最大的。
a【1】+a【2】<=a【n】时,满足条件。

AC

#include 
using namespace std;
const int maxn=5e4+10;
int a[maxn];
int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    int t;cin>>t;
    while(t--){
        int ans=-1;
        int n;cin>>n;
        for(int i=1; i<=n; i++)cin>>a[i];
        if(a[1]+a[2]<=a[n])ans=1;
        if(ans==1)cout<<1<<' '<<2<<' '<<n<<endl;
        else cout<<ans<<endl;
    }
    return 0;
}

B. Substring Removal Game

题意:

有一个01串
有以下操作

  1. 消去一个字符。
  2. 或者消去连续的1(或者0)

每个人操作一次,轮流来。(最终得分为去1的个数)。


求alice的分数

思路:

  1. 每个人肯定想去更多的1.(假如0101这样,肯定不会选择去0,因为去了0,那么对手就可以11消了。)
  2. 那么把连续1统计起来,即可。

AC

#include 
#include 
#include 
#include 
using namespace std;
char s[200];
int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    int t;cin>>t;
    while(t--){
        vector<int>v;
        cin>>(s+1);
        int len=strlen(s+1);
        int cnt=0,flag=0;
        for(int i=1; i<=len; i++){
            if(s[i]=='1')cnt++,flag=1;
            else {
                if(cnt)v.push_back(cnt);
                cnt=flag=0;
            }
        }
        if(cnt)v.push_back(cnt);
        sort(v.begin(),v.end());
        int ed=v.size()-1;
        int ans=0;
        for(int i=ed; i>=0; i-=2)ans+=v[i];
        cout<<ans<<endl;
    }
    return 0;
}

C. Good Subarrays

题意:

对于一个good subarray。
区间长度等于区间的和。

有多少个good subarray。

思路:

  1. 特别地,可以考虑11111.那么相当于5(区间长度)=5(区间和)。
  2. 这样直接找的话,显然要 n 2 n^2 n2. 那么要想办法优化。
  3. 由上面可以知道,时间复杂度是由good subarray的这个条件带的。那么就想方法,简化条件。
  4. 可以把每个数减去1. 那么对于区间长度等于区间的和。(这个条件可以被简化了,区间里每个数都减去1,假如满足条件,那么这个区间的和应该为0)可以简化成。以 i i i 为终点的子序列里,有多少个good subarray.

eg1 :11111
pre[1]=0, pre[2]=0, pre[3]=0, pre[4]=0, pre[5]=0
ans=1(i=1)+2(i=2)+3(i=3)+4(i=4)+5(i=5).

eg2: 110202
pre[1]=0, pre[2]=0, pre[3]=-1, pre[4]=0, pre[5]=-1, pre[2]=0,
ans= 1+2+0+3+1+4

AC

#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;
const int maxn=9e5+10;
ll pre[maxn];//,sum[maxn];
char s[maxn];
map<int,int>ma;
int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    int t;cin>>t;
    while(t--){
        int n;cin>>n;
        cin>>(s+1);
        ma.clear();
        pre[0]=0;//sum[0]=0;
        for(int i=1; i<=n; i++)pre[i]=pre[i-1]+s[i]-'0'-1;
        ll ans=0;
        ma[0]=1;
        for(int i=1; i<=n; i++)ans+=ma[pre[i]]++;
        cout<<ans<<endl;
    }
    return 0;
}

D. Colored Rectangles

题意:

有r个边,g个边,b个边。
两两组合矩形。

a n s = ∑ p a r e a ans=\sum_parea ans=parea

思路:

简单状态dp。

  1. 先排序。
  2. 每个状态都计算,并且取max。

AC

#include 
#include 
#include 
using namespace std;
typedef long long ll;
ll a[4][300];
ll dp[300][300][300];
int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    ll col[4];
    cin>>col[1]>>col[2]>>col[3];
    for(int i=1; i<=3; i++){
        for(int j=1; j<=col[i]; j++)cin>>a[i][j];
    }
    ll ans=0;
    for(int i=1; i<=3; i++)sort(a[i]+1,a[i]+1+col[i]);
    for(int i=col[1]; ~i; i--){
        for(int j=col[2]; ~j; j--){
            for(int k=col[3]; ~k; k--){
                dp[i][j][k]=max(dp[i][j][k],dp[i+1][j+1][k]+(ll)a[1][i+1]*a[2][j+1]);//1,2
                dp[i][j][k]=max(dp[i][j][k],dp[i+1][j][k+1]+(ll)a[1][i+1]*a[3][k+1]);//1,3
                dp[i][j][k]=max(dp[i][j][k],dp[i][j+1][k+1]+(ll)a[3][k+1]*a[2][j+1]);//2,3
            }
        }
    }
    for(int i=col[1]; ~i; i--){
        for(int j=col[2]; ~j; j--){
            for(int k=col[3]; ~k; k--){
                ans=max(dp[i][j][k],ans);
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}

你可能感兴趣的:(dp,cf菜鸡的失恋(试炼),dp)