区间dp
来源:互联网 发布:简单的表单验证js代码 编辑:程序博客网 时间:2024/06/06 03:09
POJ2955 子串括号匹配
We give the following inductive definition of a “regular brackets” sequence:
- the empty sequence is a regular brackets sequence,
- if s is a regular brackets sequence, then (s) and [s] are regular brackets sequences, and
- if a and b are regular brackets sequences, then ab is a regular brackets sequence.
- no other sequence is a regular brackets sequence
For instance, all of the following character sequences are regular brackets sequences:
(), [], (()), ()[], ()[()]
while the following character sequences are not:
(, ], )(, ([)], ([(]
Given a brackets sequence of characters a1a2 … an, your goal is to find the length of the longest regular brackets sequence that is a subsequence of s. That is, you wish to find the largest m such that for indices i1, i2, …, im where 1 ≤ i1 < i2 < … < im ≤ n, ai1ai2 … aim is a regular brackets sequence.
Given the initial sequence ([([]])]
, the longest regular brackets subsequence is [([])]
.
The input test file will contain multiple test cases. Each input test case consists of a single line containing only the characters (
, )
, [
, and ]
; each input test will have length between 1 and 100, inclusive. The end-of-file is marked by a line containing the word “end” and should not be processed.
For each input case, the program should print the length of the longest possible regular brackets subsequence on a single line.
((()))()()()([]]))[)(([][][)end
66406
//#include <bits/stdc++.h>#include <stdio.h>#include <iostream>#include <string.h>#include <algorithm>#include <map>#include <vector>#include <cmath>#include <set>#define inf 0x3f3f3f3fusing namespace std;string str;int dp[105][105];int main(){ while(cin >> str && str != "end"){ memset(dp, 0, sizeof(dp)); int len = str.length(); for(int i = 1; i <len; i++){ for(int j = 0, k = i; k < len; j++, k++){ if(str[j] == '(' && str[k] == ')' || str[j] =='[' && str[k] ==']'){ dp[j][k] = dp[j + 1][k - 1] + 2;//最外围的两个匹配 } for(int pos = j; pos < k; pos++){ dp[j][k] = max(dp[j][k], dp[j][pos] + dp[pos][k]);//最外围两个不匹配 } } } cout<< dp[0][len - 1]<< endl; } return 0;}
POJ1651
The goal is to take cards in such order as to minimize the total number of scored points.
For example, if cards in the row contain numbers 10 1 50 20 5, player might take a card with 1, then 20 and 50, scoring
If he would take the cards in the opposite order, i.e. 50, then 20, then 1, the score would be
610 1 50 50 20 5
3650
矩阵乘法 通过结合律,矩阵乘法可以大大加快
//#include <bits/stdc++.h>#include <stdio.h>#include <iostream>#include <string.h>#include <algorithm>#include <map>#include <vector>#include <cmath>#include <set>#define inf 0x3f3f3f3fusing namespace std;int n, num[105], dp[105][105];int main(){ while(scanf("%d",&n) != EOF){ for(int i = 1; i <= n; i++){ scanf("%d",&num[i]); } memset(dp, 0, sizeof(dp)); //dp[i][j]把第i到j - 1的卡片取走时的结果 for(int l = 1; l < n - 1; l++){ for(int i = 2; i + l <= n; i++){ int j = i + l; dp[i][j] = inf; for(int k = i; k < j; k++){ dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j] + num[i - 1] * num[k] * num[j]); } } } cout<<dp[2][n] <<endl; } return 0;}