POJ 1194 Zipper 【dp】【北大ACM/ICPC竞赛训练】

现在做dp题有点感觉了,以前估计会觉得这题很难,现在觉得这是道不是很水的水题

dp[i][j]代表A里前i个加上B里前j个能不能组成C的前i+j个。

至于怎么想到的呢,n是200,有1000组数据,所以猜测要dp二维,然后很容易就想到了。

这里再考虑到C[i+j]的这个元素肯定是由A[i]或B[j]组成(即A的最末尾或B的最末尾,因为要保证原来的order)

所以这就变成了dp[i][j] = dp[i-1][j] | dp[i][j-1]  (当然这是A[i]=B[j]=C[i+j])的情况。

接着想递归怎么写,每次要看正上方和左边的数值,所以从上到下从左到右就可以。边界条件是i=0或j=0的时候

 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4
 5 int dp[205][205];//dp[i][j]
 6 char a[205],b[205],c[410];
 7 int cnt;
 8 //string a1,b1,c1;
 9
10 int main(){
11     int t; cin>>t;
12     while(t--){
13         memset(dp,0,sizeof(dp));
14         cin>>a+1>>b+1>>c+1;//范围从1到strlen(a+1>
15
16         for(int i=0;i<=strlen(b+1);i++){
17             bool same=true;
18             for(int j=0;j<=i;j++){
19                 if(b[j]!=c[j]) { same=false; break; }
20             }
21             if(same) dp[0][i]=1;
22             else dp[0][i]=0;
23         }
24
25         for(int i=0;i<=strlen(a+1);i++){
26             bool same=true;
27             for(int j=0;j<=i;j++){
28                 if(a[j]!=c[j]) { same=false; break; }
29             }
30             if(same) dp[i][0]=1;
31             else dp[i][0]=0;
32         }
33
34
35         for(int i=1;i<=strlen(a+1);i++){
36             for(int j=1;j<=strlen(b+1);j++){
37                 if( a[i]==c[i+j] ) dp[i][j]|=dp[i-1][j];
38                 if( b[j]==c[i+j] ) dp[i][j]|=dp[i][j-1];
39             }
40         }
41         string ans;
42         if(dp[strlen(a+1)][strlen(b+1)]) ans="yes";
43         else ans="no";
44
45         cout<<"Data set "<<(++cnt)<<": "<<ans<<endl;
46
47     }
48
49     return 0;
50 }

原文地址:https://www.cnblogs.com/ZhenghangHu/p/9393470.html

时间: 2024-08-29 12:21:55

POJ 1194 Zipper 【dp】【北大ACM/ICPC竞赛训练】的相关文章

POJ 4979 海贼王之伟大航路 【状压dp】【北大ACM/ICPC竞赛训练】

该死的题让我想起来艾斯之死... 首先想到dp(i)代表从1到[i表示的这些岛屿]所花的最小时间,然后每次枚举最后一个岛屿以此缩小范围,但发现枚举了最后一个岛屿后没有办法转移,因为不知道倒数第二个岛屿是什么,随着倒数第二个岛屿的不同,时间的增加也会不同,也就是不具备[无后效性]. 因此想到再加一个参数去约束当前问题的状态,dp(i,j)代表1到[i代表的这些点]所需的最少时间,且这趟旅程的最后一个岛屿是j,这样就可转移了,每次枚举倒数第二岛屿:答案就是dp( (1<<n) -1,n ) 具体的

POJ 8471 切割回文 【dp】【北大ACM/ICPC竞赛训练】

1 #include<iostream> 2 #include<vector> 3 #define INF 100000 4 using namespace std; 5 6 string s; 7 char a[1005]; 8 vector<int> hui[1005];//hui[i]里的k指 k到i组成回文 9 int dp[1005];//dp[i]代表前i个字符要切几刀 10 11 int main(){ 12 int t; cin>>t; 13

POJ 6048 泰国佛塔 【dfs搜索】【疯狂剪枝!】【北大ACM/ICPC竞赛训练】

1 #include<iostream> 2 #include<cmath> 3 using namespace std; 4 5 int volumn[25],minArea[25];//volumn[i]为第i层到第1层蛋糕所用最小体积 6 int ans,n,m; //minArea[i]为第i层到第1层蛋糕所用[最小侧面积] 7 int area;//当前dfs状态所需要用的表面积 8 9 int maxV(int level,int r,int h){//用level层蛋

POJ Find the Winning Move【minmax搜索+alpha-beta剪枝】【北大ACM/ICPC竞赛训练】

1 #include<iostream> 2 using namespace std; 3 4 int row,col,chess; 5 char board[5][5]; 6 7 int minSearch(int i,int j,int alpha); 8 int maxSearch(int i,int j,int beta); 9 10 11 bool check(int r,int c){ 12 if( board[r][0]==board[r][1] && board

POJ 3436 ACM Computer Factory 【网络流】【北大ACM/ICPC竞赛训练】

我ac掉网络流的第一题! 先总结一下网络流的一些算法吧,首先是Ford-Fulkerson算法,这个算法是保证了众多网络流算法的[正确性],其他算法也是基于其[优化]得到的.Ford的算法在于引入"反向边"的概念,反向边就是反悔边,代表你给修正以前走了的边一个机会.为什么反向边是对的呢,凭空加进来一条边真的大丈夫吗,关于这个有相关正确性的证明,我也说不清楚只能直觉上去理解. 之后是Edmonds-Karp即最短增广路算法,顾名思义,每次都找到达汇点边数最少的增广路,由此避免一些特定的消

HDU 5025 Saving Tang Monk【bfs搜索】【北大ACM/ICPC竞赛训练】

bfs的难点在于怎么去表示一个问题的状态[也就是如何去判重] 1 #include<iostream> 2 #include<queue> 3 #include<cstring> 4 #include<map> 5 using namespace std; 6 7 struct node{ 8 int r,c; 9 int keys; 10 int kill;//记录当前杀死守卫的状态 11 int d;//时间 12 bool operator <

ACM/ICPC算法训练 之 数学很重要-浅谈“排列计数” (DP题-POJ1037)

这一题是最近在看Coursera的<算法与设计>的公开课时看到的一道较难的DP例题,之所以写下来,一方面是因为DP的状态我想了很久才想明白,所以借此记录,另一方面是看到这一题有运用到 排列计数 的方法,虽然排列计数的思路简单,但却是算法中一个数学优化的点睛之笔. Poj1037  A decorative fence 题意:有K组数据(1~100),每组数据给出总木棒数N(1~20)和一个排列数C(64位整型范围内),N个木棒长度各异,按照以下条件排列,并将所有可能结果进行字典序排序 1.每一

HDU 5000 Clone 规律+dp 2014 ACM/ICPC Asia Regional Anshan Online

每只羊有n个属性 下面n个数字表示每个属性的值范围为[ 0, T[i] ] 对于羊圈里的a羊和b羊,若a羊的每个属性都>=b羊,则a羊会杀死b羊. 问羊圈里最多存活多少只羊. 规律1:sum相同的羊不会互相杀死. 因为若2个羊的属性都相同,a羊某个属性要增加1,则a羊另一个属性要减少1,这样ab一定能共存. 规律2: sum不同的羊不会重合. 我们设a羊sum = x,b羊sum = y,若a,b羊能共存,但不会把ab同时放到羊圈里. 因为一定存在一只羊c ,sum = x,且c和b不能共存,既

HDU 5001 Walk 求从任意点出发任意走不经过某个点的概率 概率dp 2014 ACM/ICPC Asia Regional Anshan Online

题意: 给定n个点m条边的无向图 问: 从任意点出发任意走d步,从不经过某个点的概率 dp[i][j]表示从不经过i点的前提下,走了d步到达j点的概率. #include <iostream> #include <cstdio> #include <string.h> #include <queue> #include <vector> #include <algorithm> #include <set> using n