其他分享
首页 > 其他分享> > Educational Codeforces Round 109 D. Armchairs (dp)

Educational Codeforces Round 109 D. Armchairs (dp)

作者:互联网

传送门

题意:有一个长度为n的0/1数列,1的个数小于等于0的个数,可以把i位置上的1移到j位置(如果j位置是0),i位置变成0,j位置变成1,代价是|i-j|,问使得所有原先是1的位置都变成0的代价最小是多少。
(3<=n<=5000)

分析:我们可以把1/0的下标都拿出来,放进数组pos1\pos0里面,问题就变成了拿0去匹配1,求最小匹配代价。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int,int>
const int maxn = 5e3+10;
const int mx = 40;
const int mod = 1e9+7;
const ll inf = 0x3f3f3f3f3f3f3f3f;
const int INF = 1e9+7;
int n;
int a[maxn];
ll dp[maxn][maxn];//前i个1 匹配前j个0  i和j匹配 代价

ll mmin[maxn][maxn];
vector<int> pos0,pos1;
int main()
{
    scanf("%d",&n);
    pos0.push_back(0),pos1.push_back(0);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",a+i);
        if(a[i]) pos1.push_back(i);
        else pos0.push_back(i);
    }
    if(pos1.empty()) 
    {
        puts("0");
        return 0;
    }
    ll ans=INF;
    int n0=pos0.size()-1,n1=pos1.size()-1;
    memset(mmin,0x3f3f3f,sizeof mmin);
    memset(dp,0x3f3f3f,sizeof dp);
    for(int i=0;i<=n0;i++) dp[0][i]=mmin[0][i]=0;
    for(int i=1;i<=n1;i++)
    {
        for(int j=1;j<=n0;j++)
        {
            dp[i][j]=mmin[i-1][j-1]+abs(pos1[i]-pos0[j]);
        }
        for(int j=1;j<=n0;j++)
        {
            mmin[i][j]=min(dp[i][j],mmin[i][j-1]);
        }
    }
    for(int i=1;i<=n0;i++) 
    {
        ans=min(ans,dp[n1][i]);
    }
    cout<<ans;
    return 0;
}

标签:Educational,int,Codeforces,mmin,109,maxn,pos0,dp,pos1
来源: https://blog.csdn.net/qq_46030630/article/details/116905175