zoukankan      html  css  js  c++  java
  • Cities 题解(神仙区间dp)

    题目链接

    题目大意

    给你长度为(n(nleq 5000))的数组(a(1le a[i]le n))

    你每次可以选择一段连续且相同的元素使得它整体变为一个其他值

    求你使得所有元素相等的最少操作次数

    每个元素最多出现(15)

    题目思路

    首先可以进行缩点操作

    如果最开始相邻的一段元素相等,那么这一段可以等价为一个点

    则可以变为有(m)个相邻元素不相等的点

    假如这(m)个点都不同,那么答案就是(m-1)

    而如果中间出现了有两个相同的点(l,r),那么最优的情况肯定是把([l+1,r-1])中的元素全部变为(a[r])

    然后再整体操作([l,r])这样显然操作的次数更少,则区间在最短的操作次数下,一定能修改成端点的值

    则可以设(dp[l][r])为把这个区间变为(a[r])的最少操作次数

    而转移的话如果([l,r-1])中没有元素等于(a[r]),那么答案显然就是(dp[l][r-1]+1)

    就是先把区间([l,r-1])的元素全部变为(a[r-1])然后再全部变为(a[r])

    转移有可能比这个更优,因为([l,r-1])中可以出现(a[r])元素

    那么就可以用这个进行中间转移

    时间复杂度(O(n^2 imes 15))

    这个有点难想,建议多想几遍

    代码

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define debug cout<<"I AM HERE"<<endl;
    using namespace std;
    typedef long long ll;
    const int maxn=5e3+5,inf=0x3f3f3f3f,mod=1e9+7;
    const double eps=1e-6;
    int n,k;
    int a[maxn];
    int dp[maxn][maxn];
    signed main(){
        int _;scanf("%d",&_);
        while(_--){
            vector<int> vec[maxn];
            scanf("%d",&n);
            for(int i=1;i<=n;i++){
                scanf("%d",&a[i]);
                vec[a[i]].push_back(i);
            }
            memset(dp,0x3f,sizeof(dp));
            for(int i=1;i<=n;i++) dp[i][i]=0;
            for(int l=n;l>=1;l--){
                for(int r=l+1;r<=n;r++){
                    dp[l][r]=dp[l][r-1]+1;
                    for(int i=0;i<vec[a[r]].size();i++){
                        int x=vec[a[r]][i];
                        if(l<=x&&x<r){
                            dp[l][r]=min(dp[l][r],dp[l][x]+dp[x+1][r]);
                        }
                    }
                }
            }
            printf("%d
    ",dp[1][n]);
        }
        return 0;
    }
    
    
    
    卷也卷不过,躺又躺不平
  • 相关阅读:
    HDOJ 2577 How To Type
    HDOJ 1171 Big Event in HDU
    HDOJ 2159 FATE
    HDOJ 1176 免费馅饼
    POJ 1014 Dividing
    HDOJ 2844 Coins
    可以设置DefaultButton的TextBox控件
    setTimeout和setInterval的使用
    C# 调用ExchangeWebservice的相关代码
    实现IConfigurationSectionHandler接口来编写自定义配置
  • 原文地址:https://www.cnblogs.com/hunxuewangzi/p/14635856.html
Copyright © 2011-2022 走看看