动态规划-区间DP

1.

题目描述

假设你有一条长度为 55的木版,初始时没有涂过任何颜色。你希望把它的 5个单位长度分别涂上红、绿、蓝、绿、红色,用一个长度为 5 的字符串表示这个目标:RGBGR

每次你可以把一段连续的木版涂成一个给定的颜色,后涂的颜色覆盖先涂的颜色。例如第一次把木版涂成 RRRRR,第二次涂成 RGGGR,第三次涂成 RGBGR,达到目标。

用尽量少的涂色次数达到目标。

输入描述

输入仅一行,包含一个长度为 n的字符串,即涂色目标。字符串中的每个字符都是一个大写字母,不同的字母代表不同颜色,相同的字母代表相同颜色。

其中,1≤n≤50。

输出描述

输出仅一行,包含一个数,即最少的涂色次数。

#include 
using namespace std;
using ll=long long;
const int N=53;
ll dp[N][N];
ll inf=2e18;
char a[N];
int main()
{
  cin>>a+1;
  int n=strlen(a+1);
  for(int i=1;i<=n;i++){
    for(int j=i;j<=n;j++){
      dp[i][j]=inf;
    }
  }
for(int i=1;i<=n;i++){
  dp[i][i]=1;
}
for(int len=2;len<=n;len++){
  for(int i=1;i+len-1<=n;i++){
    int j=i+len-1;
    if(a[i]==a[j]){
    dp[i][j]=min(dp[i+1][j],dp[i][j-1]);
    }else{  
      for(int k=i;k

这道题的关键在于理解当处理两端点颜色相同与不同时的情况:

动态规划-区间DP_第1张图片理解了这个部分,剩下的就是常规的区间dp解决方法了。

2.问题描述

小蓝老师在黑板上写了 n 个数字,并且是环状排列,也就是说,第 ii 和第 i+1i+1 个数字是相邻的,同时第 n和 1 个数字是相邻的,每个数字是 0∼9 中的一个,小蓝老师要求合并这 n 个数字,规则如下:

  1. 每次只能选择两个相邻的数字进行合并。
  2. a,b 两个数合并后的结果为 (a×b)mod10 ,也就是乘积模 10 的结果,同时获得 ⌊10a×b​⌋ 的分数。
  3. 最后只剩一个数就结束。

小蓝老师想知道得分最大是多少。

输入格式

第一行输入一个整数 N ,代表数字个数。

第二行输入 N个整数,{ h1​,h2​......hn​ } 代表 NN 个数的值。

输出格式

输出一个整数,最大得分。

#include 

using namespace std;

const int maxn=250;
int dp[maxn][maxn][10];//dp[i][j][k]表示将区间[i,j]的数合并后所得值为k时的最大分数 
int a[maxn];//存储原始数据 
int Score[10][10];//用于查找两个数合并后所得分数 
int Merge[10][10];//用于查找两个数合并后的数 

void Init()//将Score和Merge数组初始化,便于后续使用 
{
    for(int i=0;i<10;i++)
    {
        for(int j=0;j<10;j++)
        {
            Score[i][j]=i*j/10;
            Merge[i][j]=i*j%10;    
        }    
    }    
}

int main()
{
    int N;
    cin>>N;
    memset(dp,-0x3f,sizeof(dp));//dp数组初始化为极小值 
    Init();
    for(int i=1;i<=N;i++)
    {
        cin>>a[i];
        a[i+N]=a[i];//环形dp,序列复制一份,长度延长一倍 
        dp[i][i][a[i]]=0;//将一个数合并,分数为0 
        dp[i+N][i+N][a[i]]=0;    
    }    
    
    for(int len=2;len<=N;len++)//枚举区间长度2~N 
    {
        for(int i=1;len+i-1<=2*N;i++)//枚举左端点i,注意右端点可达到2N 
        {
            int j=i+len-1;//计算对应右端点j 
            for(int k=i;k

这道题做了具体的注释帮助大家理解,这道题有难度,包括循环条件下数组的平移,以及对于左右两边的区间移动,大家可以好好品味尝试做一下这道题,对于自我对区间转移的帮助很大。

最后希望大家可以多多关注,点赞博主,后续博主也将继续给大家带来分享。

你可能感兴趣的:(动态规划,算法)