Codeforces Round #369 (Div. 2) C. Coloring Trees(dp)

题目链接
题意:有n棵树,m种颜料,要求现在要给这些树涂上颜料,最后涂成k段(连续颜色相同划为一段如2, 1, 1, 1, 3, 2, 2, 3, 1, 3是7段),有些树已经涂了,则不涂,其余的树只能涂一次,输入n个数(每个数为0~m),0表示还没有涂,1~m表示已经涂了哪种颜料。接下来输入n行m列,表示每棵树涂成每种颜色所要的颜料量。现在要把所有树都涂上颜料涂成k段,求最少要用的颜料量;
dp[i][j][k]表示第i颗树涂第j种颜色分成k段最少所需的颜料数
分情况考虑
1 .arr[i]==0即可涂色时,枚举颜色数和上一层的颜色数
2.arr[i]!=0不可涂色 ,只枚举上一层颜色数即可
当上一层颜色数相同时,段数不变,否则段数增一,也就是上一层的段数少一

#include<bits/stdc++.h>
using namespace  std;
#define ll long long
#define pb push_back
#define inf 199999999999
const int N=110;
ll dp[N][N][N];
ll arr[N];
ll cost[N][N];
int main()
{
    #ifdef LOCAL_DEFINE
        freopen("D://rush.txt", "r", stdin);
    #endif
    ios::sync_with_stdio(false),cin.tie(0);
    ll n,m,q;
    cin>>n>>m>>q;
    for(int i=1;i<=n;i++)
        cin>>arr[i];
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
            cin>>cost[i][j];
    }
    memset(dp,1,sizeof dp);
    if(arr[1])
    {
        dp[1][arr[1]][1]=0;
    }
    else
    {
        for(int j=1;j<=m;j++)
        dp[1][j][1]=cost[1][j];
    }
    for(int i=2;i<=n;i++)
    {
        if(arr[i])
        {
            for(int k=1;k<=i;k++)
            {
                for(int pre=1;pre<=m;pre++)
                {
                    if(pre==arr[i])
                        dp[i][arr[i]][k]=min(dp[i][arr[i]][k],dp[i-1][pre][k]);
                    else
                        dp[i][arr[i]][k]=min(dp[i][arr[i]][k],dp[i-1][pre][k-1]);
                }
            }
        }
        else
        {
            for(int j=1;j<=m;j++)
            {
                for(int k=1;k<=i;k++)
                {
                    for(int pre=1;pre<=m;pre++)
                    {
                        if(pre==j)
                            dp[i][j][k]=min(dp[i][j][k],dp[i-1][pre][k]+cost[i][j]);
                        else
                            dp[i][j][k]=min(dp[i][j][k],dp[i-1][pre][k-1]+cost[i][j]);
                    }
                }
            }
        }
    }
    ll ans=inf;
    for(int i=1;i<=m;i++)
        ans=min(ans,dp[n][i][q]);
    if(ans==inf) cout<<-1<<endl;
    else cout<<ans<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/ffgcc/article/details/81024299
今日推荐