CodeForces 711C Coloring Trees

简单$dp$。

$dp[i][j][k]$表示:前$i$个位置染完色,第$i$个位置染的是$j$这种颜色,前$i$个位置分成了$k$组的最小花费。总复杂度$O({n^4})$。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0),eps=1e-8;

LL INF=1e17;
LL dp[110][110][110];
LL p[110][110];
int c[110],n,m,k;

int main()
{
    scanf("%d%d%d",&n,&m,&k);

    for(int i=1;i<=n;i++) scanf("%d",&c[i]);

    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++) scanf("%lld",&p[i][j]);

    for(int i=0;i<=n;i++)
    {
        for(int j=0;j<=m;j++)
        {
            for(int s=0;s<=k;s++)
            {
                dp[i][j][s]=INF;
            }
        }
    }

    if(c[1]!=0) dp[1][c[1]][1]=0;
    else
    {
        for(int j=1;j<=m;j++) dp[1][j][1]=p[1][j];
    }

    for(int i=2;i<=n;i++)
    {
        if(c[i]==0)
        {
            for(int j=1;j<=m;j++)
            {
                for(int s=1;s<=i;s++)
                {
                    LL tmp=INF;
                    tmp=min(tmp,dp[i-1][j][s]);
                    for(int t=1;t<=m;t++)
                    {
                        if(t==j) continue;
                        tmp=min(tmp,dp[i-1][t][s-1]);
                    }
                    if(tmp==INF) continue;
                    else dp[i][j][s]=tmp+p[i][j];
                }
            }
        }

        else
        {
            for(int s=1;s<=i;s++)
            {
                LL tmp=INF;
                tmp=min(tmp,dp[i-1][c[i]][s]);
                for(int t=1;t<=m;t++)
                {
                    if(t==c[i]) continue;
                    tmp=min(tmp,dp[i-1][t][s-1]);
                }

                if(tmp==INF) continue;
                dp[i][c[i]][s]=tmp;
            }
        }
    }

    LL ans=INF;
    for(int j=1;j<=m;j++) ans=min(ans,dp[n][j][k]);

    if(ans==INF) printf("-1
");
    else printf("%lld
",ans);

    return 0;
}
原文地址:https://www.cnblogs.com/zufezzt/p/5821802.html