UVA-3516 Exploring Pyramids (DP)

来源:互联网 发布:js 设置css 编辑:程序博客网 时间:2024/05/01 10:24
Exploring Pyramids
Time Limit: 3000MS  64bit IO Format: %lld & %llu

Submit Status uDebug

Description

Download as PDF
Problem descriptions:
System Crawler 2016-10-16
Initialization.

题意:

给你一棵多叉树,从根结点开始,尽量往左走,走不通就回溯,把遇到字母顺次记录下来,可得到一个序列。给你一个序列,问你最多能得到几棵树与之对应。

分析:

很经典的DP数学题,咋一看好像挺复杂的还找了会儿规律,实际上只要用d(i,j)代表字符串S中Si,Si+1,...,Sj对应的树的个数,那么通过枚举k(i+2<=k<=j),可计算得到d(i,j)=sum{d(i+1,k-1)*d(k,j)},即通过枚举k遍历了树的左右分叉情况。注意d(i,i)=1,且Si≠Sj时,d(i,j)=0,因为起点终点相同。

#include <algorithm>#include <iostream>#include <sstream>#include <cstring>#include <cstdlib>#include <string>#include <vector>#include <cstdio>#include <cmath>#include <queue>#include <stack>#include <map>#include <set>using namespace std;#define INF 0x3f3f3f3fconst long long N=305;const long long mod=1e9;const double PI=acos(-1.0);typedef long long ll;int d[N][N];char s[N];int dp(int i, int j) {    if (i==j) return 1;    if (s[i]!=s[j]) return 0;        int& ans=d[i][j];    if (ans>=0) {        return ans;    }    ans=0;    for (int k=i+2; k<=j; k++) {        ans=(ans+(ll)dp(i+1, k-1)*dp(k, j))%mod;    }    return ans;}int main() {    int n;    while (scanf("%s",s)==1) {        memset(d, -1, sizeof(d));        cout<<dp(0, strlen(s)-1)<<endl;    }    return 0;}

0 0
原创粉丝点击