Codeforces - 909C - Python Indentation - 簡單dp
阿新 • • 發佈:2019-01-27
循環 -- 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 namespacestd; #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