版权声明:本文为博主原创文章,未经博主允许不得转载。 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;
}