Codeforces Hard problem(dp、字符串)

在這裏插入圖片描述
題目大意:
給定n個子字符串,對其中若干個字符串進行反轉,每次反轉產生代價Ci,最後使得字符串按照字典序排列,求最小代價和,不需要反轉時輸出-1

解題思路:
首先使字符串的兩個狀態,正序和反序,相當於從每兩個字符串中選出一個,如果選正序代價爲0,如果選反序代價爲Ci,求出最終最小代價,定義方程dp[i][j]爲當選完第i個狀態爲j的字符串時的最小代價,則有狀態轉移方程
dp[i][j]=min(dp[i][j],dp[i-1][k]+j*c[i])
注意初始化dp,字典序排列的比較
代碼:

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e5+10;
string arr[maxn][2];
ll dp[maxn][2];
int c[maxn];
int n,k;
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;++i)
        scanf("%d",&c[i]);
    for(int i=1;i<=n;++i)
    {
        cin>>arr[i][0];
        arr[i][1]=arr[i][0];
        reverse(arr[i][1].begin(),arr[i][1].end());
        for(int j=0;j<2;++j)
        {
            dp[i][j]=1e18;
            for(int k=0;k<2;++k)
                if(arr[i][j]>=arr[i-1][k])
                    dp[i][j]=min(dp[i-1][k]+j*c[i],dp[i][j]);
        }
    }
    ll ans=min(dp[n][0],dp[n][1]);
    if(ans>=1e18) puts("-1");
    else
    printf("%lld",ans);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章