1. 程式人生 > >Number String(HDU 4055,動態規劃遞推,字首和優化)

Number String(HDU 4055,動態規劃遞推,字首和優化)

點選加號檢視程式碼
#include<bits/stdc++.h>//字首和優化版本,不易理解
using namespace std;
#define ll long long
const ll maxn=1100;
const ll mod=1000000007;
ll sum[maxn][maxn];
ll dp[maxn][maxn];
char str[maxn];

int main()
{
    str[0]='*';
    str[1]='*';
    scanf("%s",str+2);
    ll len=strlen(str)-1;
    sum[1
][1]=1; dp[1][1]=1; for(ll i=2;i<=len;i++) for(ll j=1;j<=i;j++) { if(str[i]=='I'||str[i]=='?') { dp[i][j]=(dp[i][j]+sum[i-1][j-1])%mod; } if(str[i]=='D'||str[i]=='?') { ll temp
=((sum[i-1][i-1]-sum[i-1][j-1])%mod+mod)%mod; dp[i][j]=(dp[i][j]+temp)%mod; } sum[i][j]=(dp[i][j]+sum[i][j-1])%mod; } cout<<sum[len][len]<<endl; }
字首和優化版本,不易理解
#include<bits/stdc++.h>
using namespace std;
#define ll long long const ll maxn=1100; const ll mod=1000000007; ll dp[maxn][maxn]; char str[maxn]; int main() { str[0]='*'; str[1]='*'; scanf("%s",str+2); ll len=strlen(str)-1; dp[1][1]=1; for(ll i=2;i<=len;i++) for(ll j=1;j<=i;j++) { if(str[i]=='I') { for(ll k=1;k<j;k++) { dp[i][j]+=dp[i-1][k]%mod; } } else if(str[i]=='D') { for(ll k=j;k<i;k++) { dp[i][j]+=dp[i-1][k]%mod; } } else { for(ll k=1;k<=i;k++) { dp[i][j]+=dp[i-1][k]%mod; } } } ll ans=0; for(ll i=1;i<=len;i++) { ans+=dp[len][i]%mod; } cout<<ans<<endl; // for(int i=1;i<=len;i++)//測驗每一個dp是否符合預期 // for(int j=1;j<=len;j++) // { // printf("%d ",dp[i][j]); // if(j==len) // printf("\n"); // } }
超時版本,但是容易理解

思路用圖表示

首先感謝糖栗子的博文http://www.cnblogs.com/tanglizi/p/9471078.html以及他的熱心幫助

下面上圖: