zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 76 (Rated for Div. 2)E(dp||贪心||题解写法)

    题:https://codeforces.com/contest/1257/problem/E

    题意:给定3个数组,可行操作:每个数都可以跳到另外俩个数组中去,实行多步操作后使三个数组拼接起来形成升序。

       输出最小操作次数

    dp:

    #include<bits/stdc++.h>
    using namespace std;
    const int M=2e5+5;
    int dp[M][3];
    int a[M];
    ///dp[i][0]表示前i个数全属于第一个数组所要花费的最小代价
    ///dp[i][1]表示前i个数全属于第一、二个数组所要花费的最小代价
    ///!!dp[i][1]必须要保证前i个数是要连续的属于第一个数组,和连续的属于第一个数组前后分布
    int main(){
        int k1,k2,k3;
        scanf("%d%d%d",&k1,&k2,&k3);
        int n=k1+k2+k3;
        for(int i=1,x;i<=k1;i++){
            cin>>x;
            a[x]=0;
        }
        for(int i=1,x;i<=k2;i++){
            cin>>x;
            a[x]=1;
        }
        for(int i=1,x;i<=k3;i++){
            cin>>x;
            a[x]=2;
        }
        for(int i=1;i<=n;i++){
            dp[i][0]=dp[i-1][0]+(a[i]==0?0:1);
            dp[i][1]=min(dp[i-1][0],dp[i-1][1])+(a[i]==1?0:1);
            dp[i][2]=min(dp[i-1][0],min(dp[i-1][1],dp[i-1][2]))+(a[i]==2?0:1);
        }
        cout<<min(dp[n][0],min(dp[n][1],dp[n][2]));
        return  0;
    }
    View Code

    贪心:

    #include<bits/stdc++.h>
    using namespace std;
    const int M=2e5+5;
    int a[M],b[M];
    int main(){
        int n;
        int k1,k2,k3;
        scanf("%d%d%d",&k1,&k2,&k3);
        n=k1+k2+k3;
        for(int i=0;i<n;i++)
            scanf("%d",&a[i]);
        sort(a,a+k1);
        sort(a+k1,a+k1+k2);
        sort(a+k1+k2,a+n);
        int tot=0;
        for(int i=0;i<n;i++){
            if(b[tot]<a[i])
                b[++tot]=a[i];
            else{
                int pos=upper_bound(b,b+tot,a[i])-b;
                b[pos]=a[i];
            }
    
        }
        printf("%d
    ",n-tot);return 0;
    }
    View Code

     题解:枚举R,R往后的给第三个选手,然后在R的左边部分确定一个L,使其价值最优,

       考虑对于确定的L,R,答案就是,不属于L,R分割出来的数组对应的位置。

       比如L前面的数组我们要挑出属于第二,三数组的数

       这个说的就是上面的东西,也就是当前L,R的答案cnt(L,2)+cnt(L,3)+cnt(m,1)+cnt(m,3)+cnt(r,1)+cnt(r,2)

       分析:第二、四、五、六项我们可以通过枚举的R的位置来求到

          记x为第一项和第三项的和,即x=cnt(L,2)+cnt(m,1);

          现在只要知道x我们就可以算这个位置的答案了

          记posval=cnt(L,1)-cnt(L,2),我们要操作数最小,肯定要posval最大,因为posval大说明在L前面有越多满足属于第一个选手的题目。

          这时我们发现,posval+x=cnt(L,1)+cnt(m,1),这个表示R前面1的个数,这个可以很轻易的求得;

          x=cnt(R,1)-posval

    #include<bits/stdc++.h>
    using namespace std;
    const int M=2e5+5;
    int a[M];
    int L[10],R[10];
    int main(){
        int k1,k2,k3;
        scanf("%d%d%d",&k1,&k2,&k3);
        int n=k1+k2+k3;
        for(int x,i=1;i<=k1;i++){
            scanf("%d",&x);
            a[x]=1;
        }
        for(int x,i=1;i<=k2;i++){
            scanf("%d",&x);
            a[x]=2;
        }
        for(int x,i=1;i<=k3;i++){
            scanf("%d",&x);
            a[x]=3;
        }
        int ans=0,posval=0;
        for(int i=1;i<=n;i++)
            if(a[i]!=3)
                ans++;
        for(int i=1;i<=n;i++)
            R[a[i]]++;
        for(int i=1;i<=n;i++){
            L[a[i]]++;
            R[a[i]]--;
            posval=max(posval,L[1]-L[2]);///最佳的位置
            int sum=R[1]+R[2]+L[3]+L[1]-posval;
            ans=min(ans,sum);
        }
        cout<<ans<<endl;
        return 0;
    }
    View Code
  • 相关阅读:
    Software Solutions CACHE COHERENCE AND THE MESI PROTOCOL
    CACHE COHERENCE AND THE MESI PROTOCOL
    Multiprocessor Operating System Design Considerations SYMMETRIC MULTIPROCESSORS
    Organization SYMMETRIC MULTIPROCESSORS
    PARALLEL PROCESSING
    1分钟内发送差评邮件
    Secure Digital
    SYMMETRIC MULTIPROCESSORS
    A Taxonomy of Parallel Processor Architectures
    parallelism
  • 原文地址:https://www.cnblogs.com/starve/p/11864900.html
Copyright © 2011-2022 走看看