zoukankan      html  css  js  c++  java
  • 区间DP学习总结

    这段时间学习了区间DP,所以试着把学到的东西稍作总结,以备不时之需。

    学习区间DP首先要弄清区间DP是为了解决什么问题:一般的DP主要是特征是一次往往只操作一个数值或者存储可以不连续的物品的状态(比如背包问题中,每一个点存储的状态中,拿到的物品的编号并不要求一定连续)而区间DP,则是要求DP数组中每个点的状态映射到原本的数据集中都会与附近的元素有所关联,其中,连续区间的长度、起始点的位置、子区间分割点的位置都会有所变化,而这和一般的DP有所不同,故一般用区间DP。

    区间DP的一般格式(参考博客)

    for(int l=1;l<=n;l++)   //每次处理的区间的长度
        for(int i=0;i+l-1<len;i++) //每次区间的起点
            int j=i+l-1;   //每次区间的终点
            for(int k=i;k<j;k++) //区间的分割点
                //TODO:状态转移方程

    两个个例题:

    一.POJ1561

    AC代码:

    #include <stdio.h>
    #include <iostream>
    #include <string.h>
    using namespace std;
    const int maxn=105;
    
    int dp[maxn][maxn];
    int num[maxn];
    
    int main(){
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&num[i]);
        }
        
        for(int l=2;l<n;l++){
            for(int i=2;i+l<=n+1;i++){
                dp[i][i+l-1]=100000000;
                for(int k=i;k<i+l-1;k++){
                    dp[i][i+l-1]=min(dp[i][i+l-1],dp[i][k]+dp[k+1][i+l-1]+num[i-1]*num[k]*num[i+l-1]);
                }
            }
        }
        printf("%d
    ",dp[2][n]);
        return 0;    
    }

    二.POJ2955

    AC代码:

    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    using namespace std;
    const int maxn=105;
    
    char str[maxn];
    int dp[maxn][maxn];
    
    int check(char a,char b){
        if(a=='('&&b==')'){
            return 1;
        }
        if(a=='['&&b==']'){
            return 1;
        }else{
            return 0;
        }
    }
    
    int main(){
        while(scanf("%s",str)!=EOF){
            if(str[0]=='e')break;
            int len=strlen(str);
            memset(dp,0,sizeof(dp));
             
            for(int i=0;i<len;i++){
                dp[i][i]=0;
                if(check(str[i],str[i+1]))dp[i][i+1]=2;
                else dp[i][i+1]=0;
            }
            
            for(int l=3;l<=len;l++){//区间的长度 
                for(int i=0;i+l-1<len;i++){//开始的位置 
                    int j=i+l-1;
                    if(check(str[i],str[j]))dp[i][j]=dp[i+1][j-1]+2;
                    for(int k=i;k<j;k++){ //区间的分割 
                        dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]);
                    }
                }
            }
            printf("%d
    ",dp[0][len-1]);
                    
        }
        return 0;
    }
  • 相关阅读:
    EOS 数据库RAM使用量的计算
    EOS require_auth函数
    EOS测试链智能合约部署调用
    安装EOS合约工具eosio.cdt
    Linux Ubuntu下搭建Flutter桌面环境
    VMware虚拟机与物理机共享文件的方法总结
    虚拟机macOS Mojave10.14安装XCode10.1
    VMware14 安装 macOS Mojave教程
    VMware 14安装OS X10.11
    Mac OS虚拟机安装VMware Tools的方法
  • 原文地址:https://www.cnblogs.com/87hbteo/p/7196182.html
Copyright © 2011-2022 走看看