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 [([])]
.
Input
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.
Output
For each input case, the program should print the length of the longest possible regular brackets subsequence on a single line.
Sample Input
((())) ()()() ([]]) )[)( ([][][) end
Sample Output
6 6 4 0 6
//#include <bits/stdc++.h>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#include <map>
#include <vector>
#include <cmath>
#include <set>
#define inf 0x3f3f3f3f
using 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
Input
Output
Sample Input
6 10 1 50 50 20 5
Sample Output
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 0x3f3f3f3f
using 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;
}