zoukankan      html  css  js  c++  java
  • 【henuacm2016级暑期训练-动态规划专题 B】Coloring Trees

    【链接】 我是链接,点我呀:)
    【题意】

    在这里输入题意

    【题解】

    f[i][j][k]前i个位置,第i个位置放j这个颜色,然后形成了k个联通块的最小花费 分第i个位置有没有已经放颜色两种情况考虑。 如果有放的话。枚举前一个位置的颜色以及前i-1个位置形成的联通块的数目 如果没有放的话。枚举当前以及前一个的颜色以及前i-1个位置形成的联通块数目 有放不用加代价。 没有放的话加上放的代价就会。

    最后在f[n][1..m][k]里面找最小值

    【代码】

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 100;
    
    int n,m,k,c[N+10],p[N+10][N+10];
    long long f[N+10][N+10][N+10];
    
    void get_min(long long &x,long long y){
        if (x==-1) x = y;
        if (y<x) x = y;
    }
    
    int main()
    {
        #ifdef LOCAL_DEFINE
            freopen("D:\rush.txt","r",stdin);
        #endif // LOCAL_DEFINE
    
        ios::sync_with_stdio(0),cin.tie(0);
        cin >> n >> m>>k;
        for (int i = 1;i <= n;i++) cin >> c[i];
        for (int i = 1;i <= n;i++)
            for (int j = 1;j <= m;j++)
                cin >> p[i][j];
        memset(f,255,sizeof f);
        f[0][0][0] = 0;
        for (int i = 1;i <= n;i++){
            if (c[i]!=0){
                //第i个位置的颜色已经固定。
                //枚举前一个的颜色
                for (int j = 0;j <= m;j++)
                    for (int k = 0;k <= i-1;k++)
                        if (f[i-1][j][k]!=-1){
                            if (j!=c[i]){
                                get_min(f[i][c[i]][k+1],f[i-1][j][k]);
                            }else{
                                get_min(f[i][c[i]][k],f[i-1][j][k]);
                            }
                        }
            }else{
                //这一个的颜色和前一个的颜色都要枚举
                for (int j = 1;j <= m;j++)
                    for (int jj = 0;jj <= m;jj++)
                        for (int k = 0;k <= i-1;k++){
                            if (f[i-1][jj][k]!=-1){
                                if (j!=jj){
                                    get_min(f[i][j][k+1],f[i-1][jj][k]+p[i][j]);
                                }else{
                                    get_min(f[i][j][k],f[i-1][jj][k]+p[i][j]);
                                }
                            }
                        }
            }
        }
        //f[n][1..m][k]
        long long ans = -1;
        for (int i = 1;i <= m;i++)
            if (f[n][i][k]!=-1)
                get_min(ans,f[n][i][k]);
        cout<<ans<<endl;
        return 0;
    }
    
    
  • 相关阅读:
    学习 iOS多线程开发 Demo示意
    python(数字Number)
    python(元组)
    python(列表)
    python(一)
    APP自动化测试框架搭建(转载)
    Appium真机运行Device Name获取方法
    关于android sdk manager在下载包时没有android intel x86 atom system image等项
    adb shell命令查看当前与用户交互的activity
    SDK更新
  • 原文地址:https://www.cnblogs.com/AWCXV/p/9303235.html
Copyright © 2011-2022 走看看