1. 程式人生 > >Codeforces - 909C - Python Indentation - 簡單dp

Codeforces - 909C - Python Indentation - 簡單dp

循環 -- include end 遞推 換行 its fine bit

好像以前做過,但是當時沒做出來,看了題解也不太懂。

一開始以為只有上面的for有了循環體,這裏的statement就可以隨便放,但其實並不是這樣,statement的位置會取消比它縮進更多或相等的for的可append性。所以設計dp順序的時候要用dp[i][j]表示第i行剩余可選for循環數量為j的選法數。那麽遞推公式也不難(才怪),看看代碼就好了。

有幾個可以優化的,一個是滾動數組,另一個是線性求前綴和然後均攤O(1)減少一個維度的時間復雜度。

註意讀入%c之前要加一個空格來過濾前面還保留在流中的換行符

#include<bits/stdc++.h>
using namespace
std; #define ll long long ll dp[5005][5005]; char ch[5005]; int n; int p=1000000007; int main(){ scanf("%d",&n); for(int i=0;i<n;i++){ scanf(" %c",&ch[i]); //printf("%c\n",ch[i]); } int cntf=0; if(ch[0]==f) cntf++; dp[0][cntf]=1; //可跟隨的f的數量 /*for(int j=0;j<=cntf;j++){ printf("dp[%d][%d]=%lld\n",0,j,dp[0][j]); } printf("\n");
*/ for(int i=1;i<n;i++){ if(ch[i]==f){ cntf++; if(i-1>=0&&ch[i-1]==f){ //dp[i]=dp[i-1]; //不得不跟隨 for(int j=1;j<=cntf;j++){ dp[i][j]=dp[i-1][j-1]; } }
else if(i-1>=0&&ch[i-1]==s){ //任選一個f進行跟隨 ll sum=0; for(int j=0;j<=cntf-1;j++){ sum=(sum+dp[i-1][j])%p; } ll presum=0; for(int j=1;j<=cntf;j++){ dp[i][j]=(sum-presum+p)%p; presum=(presum+dp[i-1][j-1])%p; } } } else{ if(i-1>=0&&ch[i-1]==f){ //dp[i]=dp[i-1]; //不得不跟隨 for(int j=0;j<=cntf;j++){ dp[i][j]=dp[i-1][j]; } } else if(i-1>=0&&ch[i-1]==s){ //任選一個f進行跟隨 ll sum=0; for(int j=0;j<=cntf;j++){ sum=(sum+dp[i-1][j])%p; } ll presum=0; for(int j=0;j<=cntf;j++){ dp[i][j]=(sum-presum+p)%p; presum=(presum+dp[i-1][j])%p; } } } /*for(int j=0;j<=cntf;j++){ printf("dp[%d][%d]=%lld\n",i,j,dp[i][j]); } printf("\n");*/ } ll sum=0; for(int j=0;j<=cntf;j++){ sum=(sum+dp[n-1][j])%p; } printf("%lld\n",sum); }

---恢復內容結束---

Codeforces - 909C - Python Indentation - 簡單dp