(review)zoj1276 区间dp+路径输出

【题解】:经典的区间dp,并且记录下了dp的path

因为是递归得到的path,所以递归压栈按从里到外的顺序得到path就可以了

输出嵌套括号部分很好的考察了对栈的理解,和递归执行的顺序。

注意题目输出中有的地方有空格


 1  //zoj1276 路径输出用到了栈的思想,比较考验思维
2 #include<iostream>
3 #include<string.h>
4 #include<stdio.h>
5 #define maxn 13
6 using namespace std;
7 int N;
8 int a[maxn],b[maxn],dp[maxn][maxn],path[maxn][maxn];
9 int cas=0;
10 int DP(int i,int j){
11 if (dp[i][j]!=-1) return dp[i][j];
12 if (i==j) return dp[i][j]=0;
13 int M=99999999;
14 for(int k=i;k+1<=j;k++){
15 int d=DP(i,k)+DP(k+1,j)+a[i]*b[k]*b[j];
16 if (d<M){
17 M=d;
18 dp[i][j]=M;
19 path[i][j]=k;
20 }
21 }
22 return dp[i][j];
23 }
24 void PRINT(int i,int j){
25 if (i<j) printf("(");
26 if (i==j) {
27 printf("A%d",i);
28 return ; //important
29 }
30
31 PRINT(i,path[i][j]);
32 printf(" x ");
33 PRINT(path[i][j]+1,j);
34
35 if (i<j) printf(")");
36
37 }
38 int main(){
39 cas=0;
40 while(~scanf("%d",&N) && N>0){
41 cas++;
42 for(int i=1;i<=N;i++){
43 scanf("%d%d",&a[i],&b[i]);
44 }
45 memset(dp,-1,sizeof(dp));
46 //for(int i=1;i<N;i++) path[i][i+1]=i;
47 printf("Case %d: ",cas);
48 DP(1,N);
49 // cout<<path[2][3];
50 PRINT(1,N);
51 printf("\n");
52
53 }
54 return 0;
55
56 }

(review)zoj1276 区间dp+路径输出,布布扣,bubuko.com

时间: 2024-10-13 07:15:20

(review)zoj1276 区间dp+路径输出的相关文章

URAL 1183 Brackets Sequence DP 路径输出

题意:长度小于100的字符串s只由四种字符"()[]"组成,求以该串为子串的最短的合法串.合法串递归定义为: (1)空串合法 (2)如果S合法,则(S).[S]合法 (3)如果A.B合法,则AB合法 思路: 设dp[i][j]为s(i,j)变为合法串后,合法串的长度或需要添加的字符的个数,状态转移: (1)如果s[i]和s[j]匹配,dp[i,j]=dp[i+1,j-1]. (2)如果不匹配,划分s(i,j)为s(i,k)和s(k+1,j),划分后dp[i,j]=dp[i,k]+dp[

uva 10453 Make Palindrome (区间DP + 递归输出)

uva 10453 Make Palindrome 题目大意:给出一段字符串,要求求出最少加入几个字符(任意位置),可以让该字符串变成会问字符串,并输出修改以后的回文字符串. 解题思路:dp[i][j]代表了将该字符串从第i位到第j位变成回文字符串最少要添加的字符.当S[i]==S[j],dp[i][j]=dp[i+1][j?1]当S[i]!=S[j],dp[i][j]=min(dp[i+1][j],dp[i][j?1])+1,在DP的过程中记录对该区间的操作类型,最后递归输出. #includ

poj1141 区间dp+路径

1 //Accepted 176 KB 47 ms 2 //感谢大神们为我们这群渣渣铺平前进的道路!! 3 //用scanf("%s",s)!=EOF WA到死 4 #include <cstdio> 5 #include <cstring> 6 #include <iostream> 7 using namespace std; 8 const int imax_n = 105; 9 const int inf = 100000000; 10 ch

选课 树形dp+路径输出

#include<iostream> #include<cstdio> #include<cstring> #define maxn 2010 using namespace std; int n,m,v[maxn],sum[maxn],son[maxn][maxn],s[maxn][3],f[maxn][maxn]; bool falg[maxn]; int Dfs(int k,int p) { if(k==0&&p!=m||p==0)return 0

POJ 1141 Brackets Sequence (区间dp 记录路径)

题目大意: 给出一种不合法的括号序列,要求构造出一种合法的序列,使得填充的括号最少. 思路分析: 如果只要求输出最少的匹配括号的数量,那么就是简单的区间dp dp[i][j]表示 i - j 之间已经合法了最少添加的括号数. 转移 就是 dp[i] [j] = min  (dp[i+1][j]+1 , dp[ i+ 1] [ k -1 ] + dp[k+1] [j] (i k 位置的括号匹配)) 其次我们要记录路径,你发现  如果 dp [i] [j] 是由 dp [i+1] [j] 转移过来的

poj 2250 Compromise dp lcs 路径输出

点击打开链接题目链接 Compromise Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6520   Accepted: 2922   Special Judge Description In a few months the European Currency Union will become a reality. However, to join the club, the Maastricht criteria

uva1626 poj 1141 Brackets Sequence 区间dp 打印路径

// poj 1141 Brackets Sequence // 也是在紫书上看的一题,uva就是多了一个t组数据. // 经典区间dp // dp(i,j)表示区间[i,j]内所需要增加的括号数目 // 则分为两种情况 // 一种是s[i]和s[j]是匹配的则 // dp[i][j] = min(dp[i][j],dp[i+1][j-1]) // 另外一种情况是不匹配 // dp[i][j] = min(dp[i][j],dp[i][k]+dp[k+1][j]){i<k<j}; // 但是无

CSU1622: Generalized Roman Numerals(区间DP)

Description Input Output Sample Input IVX XIXIX 0 Sample Output Case 1: 4 6 Case 2: 8 10 28 30 32 HINT Source 题意:给出一个罗马数字,要你输出这罗马数字所有可能组成的数 罗马数字组成规则: 1.左边的字母大于等于右边的字母,两者相加 2.左边的字母小于右边的字母,后者减去前者 3.一个罗马数字串,可以随意组合 思路:这题要用区间dp处理,dp[i][j],代表位置i之后的j个数所能组成的

黑书例题 Fight Club 区间DP

题目可以在bnuoj.soj等OJ上找到. 题意: 不超过40个人站成一圈,只能和两边的人对战.给出任意两人对战的输赢,对于每一个人,输出是否可能是最后的胜者. 分析: 首先序列扩展成2倍,破环成链. dp[i][j]表示i和j能够相遇对打,那么dp[i][i+n]为真代表可以成为最后胜者. 枚举中间的k,若i和j都能和k相遇,且i和j至少一人能打赢k,那么i和j可以相遇. 复杂度o(n^3) 1 #include<cstdio> 2 #include<cstring> 3 usi