您的位置:首页 > 产品设计 > UI/UE

UVA-1626 Brackets sequence

2015-12-07 00:17 471 查看
Brief description



Algorithm analyse

fgets()

现在不用理解太深,到学的时候再用。

现在fgets()一般都是整行输入用,比gets()稳定,遇到换行符或者EOF停止

遇到换行符时会存\0,遇到EOF则不用,

3个参数,一般我使用时最后面输入流从屏幕输入是stdin

具体可以看

点击打开链接

sscanf()

与scanf()不同的是,前者从已知字符串读取,后者从屏幕读取。

有3个参数,注意第2个参数的用法即可。

具体可以看

点击打开链接

区间dp。

第一个是形如(A)的转换(满足mathch)

第二个是形如AB的转换。

空序列的定义dp[i+1][i]为0

Code

记忆化搜索:
#include <iostream>
#include <map>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <queue>
#include <stack>
#include <functional>
#include <set>
#include <cmath>
using namespace std;
#define pb push_back
#define PB pop_back
#define bk back()
#define fs first
#define se second
#define sq(x) (x)*(x)
#define eps (1e-10)
#define INF (0x3f3f3f3f)
#define clr(x) memset((x),0,sizeof (x))
#define cp(a,b) memcpy((a),(b),sizeof (b))

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> P;

const int maxn = 100 + 5;
char S[maxn];
int n, d[maxn][maxn];

bool match(char a, char b) {
return (a == '(' && b == ')') || (a == '[' && b == ']');
}

int dp(int i, int j) {
if(i > j) return 0;
if(i == j) return 1;
int& ans = d[i][j];
if(ans >= 0) return ans;
ans = n;
if(match(S[i], S[j])) ans = min(ans, dp(i+1, j-1));
for(int k = i; k < j; k++)
ans = min(ans, dp(i, k) + dp(k+1, j));
return ans;
}

void print(int i, int j) {
if(i > j) return ;
if(i == j) {
if(S[i] == '(' || S[i] == ')') printf("()");
else printf("[]");
return;
}
int ans = dp(i, j);
if(match(S[i], S[j]) && ans == dp(i+1, j-1)) {
printf("%c", S[i]); print(i+1, j-1); printf("%c", S[j]);
return;
}
for(int k = i; k < j; k++)
if(ans == dp(i, k) + dp(k+1, j)) {
print(i, k); print(k+1, j);
return;
}
}

void readline(char* S) {
fgets(S, maxn, stdin);
}

int main() {
int T;

readline(S);
sscanf(S, "%d", &T);
readline(S);

while(T--) {
readline(S);
n = strlen(S) - 1;
memset(d, -1, sizeof(d));
print(0, n-1);
printf("\n");
if(T) printf("\n");
readline(S);
}
return 0;
}

递推:

#include <iostream>
#include <map>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <queue>
#include <stack>
#include <functional>
#include <set>
#include <cmath>
using namespace std;
#define pb push_back
#define PB pop_back
#define bk back()
#define fs first
#define se second
#define sq(x) (x)*(x)
#define eps (1e-10)
#define INF (0x3f3f3f3f)
#define clr(x) memset((x),0,sizeof (x))
#define cp(a,b) memcpy((a),(b),sizeof (b))

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> P;

const int maxn=105;
char s[maxn];
int n;
int d[maxn][maxn];

bool match(int a,int b)
{
return(s[a]=='('&&s[b]==')')||(s[a]=='['&&s[b]==']');
}

void DP()
{
for(int i=0;i<n;i++)
{
d[i+1][i]=0;
d[i][i]=1;
}
for(int i=n-2;i>=0;i--)
{
for(int j=i+1;j<n;j++)
{
d[i][j]=n;
if(match(i,j)) d[i][j]=min(d[i][j],d[i+1][j-1]);
for(int k=i;k<j;k++)
d[i][j]=min(d[i][j],d[i][k]+d[k+1][j]);
}
}
}

void print(int i,int j)
{
if(i>j) return;
if(i==j)
{
if(s[i]=='['||s[j]==']') printf("[]");
else       printf("()");
return;
}
if(match(i,j)&&d[i][j]==d[i+1][j-1])
{
printf("%c",s[i]);
print(i+1,j-1);
printf("%c",s[j]);
return;
}
for(int k=i;k<j;k++)
if(d[i][j]==d[i][k]+d[k+1][j])
{
print(i,k);
print(k+1,j);
return ;
}
}

void readline(char* s)
{
fgets(s,maxn,stdin);
}

int main()
{
int T;
readline(s);
sscanf(s,"%d",&T);
readline(s);
while(T--)
{
memset(d,-1,sizeof(d));
readline(s);
n=strlen(s)-1;
DP();
print(0,n-1);
printf("\n");
if(T) printf("\n");
readline(s);
}
return 0;
}


Summary

1.上述都是LRJ的代码,对于困难一些的题,还是无从下手,但是千万别放弃,坚持

2.做完了这个题,感觉对最优矩阵求和,和最优三角剖分有个模糊的认识,等做完下个题总结一下

递推的思路

首先确定一个顺序,从左向右还是从右向左,均可。

最小2个大小的区间进行dp。

直到完全。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: