Codeforcesラウンド#585(DIV。2)D、E

D

問題の意味

シーケンスの文字列、各文字が数字であり、多くの未知の場所があり、二人は番号を記入する必要があり、前の勝利に元 n個 2 \ FRAC {N} {2} そして、後に n個 2 \ FRAC {N} {2} 同じ勝利を持っている、異なります。

問題の解決策

私たちは、アカウントに既存の貧弱な数字を取る、元マイナス後者の違い バツ バツ
そして、疑問符の数の違い
私はすべての必要な部品で埋めることができるので、二つの異なるシンボル場合、後者は失敗する運命にあることを示すプラス 9 9 、差を大きくするために、後者は私が埋めることはできないだろう 0 0 、私は任意の場所を選択し、同じ頃、最後の疑問符、塗りつぶしの違いを増やします 9 9 塗りつぶしに差を低減するために、 0 0 ほとんどは、私は現在の操作をキャンセルしています、。

同じ数は、考えることができるならば、後者ISは、余分な疑問符を獲得する場合 * 9 * 9 少なく、特定の、そしてかつての意志グラブない場合、我々は唯一の疑問符の差の半分を得ることができ、違いを作る必要があります。もし疑問符の差の半分 > > デジタル貧しい、そして前者は全体の塗りの上にそれを取ることができます 9 9 ギャップ増加につながります。しかし、単に適切な言葉ならば、どんなには、前者奪うが、どのように記入する方法を、私は、彼の後に彼女と私、この操作に必要事項を記入して作ることができます 9 9 、同時期に残りのブラケットは、彼は私が反対側に缶を埋め、次のいずれかを満たしました。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 200050;
 
int A[maxn],B[maxn];
int sum[maxn],pre0[maxn],pre1[maxn];
 
int main(){
    int n;cin>>n;
    string str;cin>>str;
    int l=0,r=0,ln=0,rn=0;
    for(int i=1;i<=n/2;i++){
        if(str[i-1]=='?')ln++;
        else l+=str[i-1]-'0';
    }
    for(int i=n/2+1;i<=n;i++){
        if(str[i-1]=='?')rn++;
        else r+=str[i-1]-'0';
    }
    if(l==r){
        if(ln==rn)puts("Bicarp");
        else puts("Monocarp");
    }
    else{
        if(l<r&&ln>rn){
            int tmp=(ln-rn)/2;
            if(tmp*9==r-l)puts("Bicarp");
            else puts("Monocarp");
        }
        else if(l>r&&ln<rn){
            int tmp=(rn-ln)/2;
            if(tmp*9==l-r)puts("Bicarp");
            else puts("Monocarp");
        }
        else puts("Monocarp");
    }
}

E

問題の意味

n個 n個 の数字、 メートル メートル シード値 1 メートル 20 (1 \当量M \当量20)
この切り替え、必要な操作の最小数を達成するために、隣接する連続的なセグメント内のすべて同じ値を必要とします。

問題の解決策

最後に、 222111333444 222111333444 この状態は、我々は隣接交換バブルソートと考えることができます。
しかし、我々は、この種の最終状態は階乗まず、我々はこの状態を知っておく必要がありますので、ですが、複合体が大きすぎるわかりません。
第二の形態は、圧力、からです 1 < < 20 = 1 E 6 1 << 20 = 1E6
詳細な形状の加圧状態を考慮に逆数の要件を取って、私たちはそれぞれのソートは(影響を与えない)最も大きい変換することができ、表示されソートされた状態となっています。これは、計算することが簡単にそれを作る、自分自身よりも大きな電流の数をカウントするために、そして最終的にはすべてのソートの数を述べるために、新しい番号を挿入します。
明らかに転送します。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2000050;
 
int n;
int A[maxn],cnt[maxn];
ll pre[30][30],dp[maxn];
 
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        scanf("%d",&A[i]);
        for(int j=1;j<=20;j++){
            pre[A[i]][j]+=cnt[j];
        }
        cnt[A[i]]++;
    }
    memset(dp,0x3f,sizeof(dp));
    dp[0]=0;
    for(int i=0;i<(1<<20);i++){
        ll tmp;
        for(int j=1;j<=20;j++){
            if(i&(1<<(j-1)))continue;
            tmp=0;
            for(int k=1;k<=20;k++){
                if(i&(1<<(k-1)))tmp+=pre[j][k];
            }
            dp[i+(1<<(j-1))]=min(dp[i+(1<<(j-1))],dp[i]+tmp);
        }
    }
    cout<<dp[(1<<20)-1]<<endl;
}
公開された203元の記事 ウォン称賛17 ビュー20000 +

おすすめ

転載: blog.csdn.net/mxYlulu/article/details/104115344