紫书第九章-----动态规划初步(例题9-9 Cutting Sticks UVA - 10003 、例题9-10 Brackets sequence UVA - 1626 )

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ccnuacmhdu/article/details/81700845

例题9-9 Cutting Sticks UVA - 10003

【分析】
区间DP题目(分治思想)

/*
    状态:d[i][j]表示从i到j最优解
    状态转移:d[i][j]=min(d[i][k],d[k][j]}+a[j]-a[i],d[i][j]),i<k<j
*/
#include<iostream>

using namespace std;

const int maxn=60;
const int INF=(1<<30);

int n;
int len;
int a[maxn];
int d[maxn][maxn];

int dp(int i,int j){
    int &ans=d[i][j];
    if(ans>=0) return ans;
    ans=INF;
    for(int k=i+1;k<=j-1;k++){
        ans=min(dp(i,k)+dp(k,j)+a[j]-a[i],ans);
    }
    return ans;
}

int main()
{
    while(cin>>len && len){
        cin>>n;
        for(int i=1;i<=n;i++){
            cin>>a[i];
        }
        a[0]=0;//坐标0
        a[n+1]=len;//坐标len
        for(int i=0;i<=n+1;i++){
            for(int j=0;j<=n+1;j++){
                if(i+1==j){
                    d[i][j]=0;
                }else{
                    d[i][j]=-1;
                }
            }
        }
        cout<<"The minimum cutting is "<<dp(0,n+1)<<"."<<endl;
    }
    return 0;
}

例题9-10 Brackets sequence UVA - 1626

【分析】
根据《算法竞赛入门经典(第2版)》278页-279页思路和代码,加以理解!!

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

const int maxn=100+10;
int T;
char str[maxn];
int len;
int d[maxn][maxn];

bool match(char a,char b){
    if(a=='(' && b==')') return true;
    if(a=='[' && b==']') return true;
    return false;
}

void dp(){
    for(int i=0;i<len;i++){
        d[i][i]=1;
        d[i+1][i]=0;
    }
    for(int i=len-1;i>=0;i--){
        for(int j=i+1;j<len;j++){
            d[i][j]=len;
            if(match(str[i],str[j])){
                d[i][j]=min(d[i][j],d[i+1][j-1]);//d[i+1][i]=0正是为了这句代码,可能i+1=(j-1)+1
            }
            for(int k=i;k<j;k++){
                d[i][j]=min(d[i][j],d[i][k]+d[k+1][j]);
            }
        }
    }
}

//打印输出的过程其实就是按照上面的dp来写的
void print(int i,int j){
    if(i>j) return;
    if(i==j){
        if(str[i]=='(' || str[i]==')') cout<<"()";
        else cout<<"[]";
        return;
    }
    int ans=d[i][j];
    if(match(str[i],str[j]) && ans==d[i+1][j-1]){
        cout<<str[i];
        print(i+1,j-1);
        cout<<str[j];
        return;
    }
    for(int k=i;k<j;k++){
        if(ans==d[i][k]+d[k+1][j]){
            print(i,k);
            print(k+1,j);
            return;
        }
    }
}

int main()
{
    cin>>T;
    getchar();
    while(T--){
        getchar();
        fgets(str,maxn,stdin);
        len=strlen(str)-1;//str包含换行符
        dp();
        print(0,len-1);
        cout<<endl;
        if(T) cout<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/ccnuacmhdu/article/details/81700845