当前位置: 代码网 > it编程>编程语言>C/C++ > 动态规划区间DP

动态规划区间DP

2024年07月31日 C/C++ 我要评论
动态规划区间DP包含普通区间dp,环形dp

动态规划区间dp

普通区间dp

在这里插入图片描述

石子合并(蓝桥官网1233)

请添加图片描述

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int n=300;
int n,a[n],s[n],f[n][n];
signed main(){
    cin>>n;
    memset(f,127,sizeof(f));//初始化f为较大值
    for(int i=1;i<=n;i++){
      cin>>a[i];
      f[i][i]=0;//长度为1的区间不用合并,代价0
      s[i]=s[i-1]+a[i];//前缀和sum(i,j)
    }
    for(int len=2;len<=n;len++)
      for(int i=1;i+len-1<=n;i++){
        int j=i+len-1;
        for(int k=i;k<j;k++){
          f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]+s[j]-s[i-1]);
        }
      }
    cout<<f[1][n];
}

涂色(蓝桥官网926)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

请添加图片描述

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int n=60;
int f[n][n];
signed main(){
    string s;cin>>s;
    int n=s.size();
    memset(f,127,sizeof(f));
    for(int i=0;i<n;i++)f[i][i]=1;

    for(int len=2;len<=n;len++)
      for(int i=0;i+len-1<n;i++){
        int j=i+len-1;
        if(s[i]==s[j])//两端颜色相同
          f[i][j]=min(f[i+1][j],f[i][j-1]);
        else{//区间dp
          for(int k=i;k<j;k++)
          f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]);
        }
      }
      cout<<f[0][n-1];
}

制作回文串(蓝桥官网1547)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

请添加图片描述

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int n=2e3+9;
string s;
int n,m,w1[30],w2[30],f[n][n];
signed main(){
  cin>>m>>n>>s;
  for(int i=1;i<=m;i++){
    char ch;cin>>ch;
    cin>>w1[ch-'a']>>w2[ch-'a'];
  }
  for(int len=2;len<=n;len++)
    for(int i=0;i+len-1<n;i++){
      int j=i+len-1;
      if(s[i]==s[j]){//左右同色
        if(len==2) f[i][j]==0;
        else f[i][j]=f[i+1][j-1];
      }
      else //区间dp
      f[i][j]=min(f[i+1][j]+min(w1[s[i]-'a'],w2[s[i]-'a']),
                  f[i][j-1]+min(w1[s[j]-'a'],w2[s[j]-'a']));
    }
    cout<<f[0][n-1];
}

环形区间dp

在这里插入图片描述
在这里插入图片描述

能量项链(蓝桥官网557)

请添加图片描述

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int n=209;
int n,a[n*2],dp[n*2][n*2];
signed main(){
  ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
  cin>>n;
  for(int i=1;i<=n;i++){
    cin>>a[i];
    a[n+i]=a[i];//环形区间dp,复制
  }
  for(int len=2;len<=n;len++)
  for(int i=1;i+len-1<=n*2;i++){
      int j=i+len-1;
      for(int k=i;k<j;k++)
      dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]+a[i]*a[k+1]*a[j+1]);
  }
  int ans=0;
  for(int i=1;i<=n;i++)
  ans=max(ans,dp[i][i+n-1]);
  cout<<ans;
}
(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com