再入DP:尋找SCAU
阿新 • • 發佈:2018-12-09
Description
我們知道華農校園裡很多地方都有SCAU(South China Agricultural University)的標誌,如五山一條街旁邊的草坪就有一個綠綠的"SCAU"。
小To今年剛考進了華農,他來到學校尋找著校園內SCAU的標誌。
現在小To得到了一個字串,他想知道這個字串裡有多少個SCAU的子序列(不必是連續的,但是有序的)
輸入格式
一個只包含S、C、A、U四種字母(大寫)的字串s, 且1<= |s| <= 100000,其中|s|是字串s的長度
輸出格式
輸出字串s中SCAU序列的個數,由於答案可能會很大,請對其求模1000000007(1e9+7)後輸出
輸入樣例
SCAUUU
輸出樣例
3
分析:
一開始的想法是把S、C、A、U的個數分別存下來,然後相乘,後來想了一下發現這是錯誤的想法,因為SCAU是要有序的,這樣算得的子序列其實是無序的,那麼究竟要怎麼做呢?類比求最長上升子序列,我們能不能把SCAU看成一個上升的序列,即字元C比字元S大,字元A比字元C大,字元U比字元A大,那麼,求該字串有多少個SCAU子序列可分解為每個U前有多少個SCA序列,把每個U前SCA序列個數相加即可;而求SCA序列共有多少個可以分解為每個A前有多少個SC序列,再把每個A前SC序列個數相加即可;求SC序列總數則可分解為每個C前有多少個S,再把每個C前S個數相加即可。
#include <stdio.h> char ch[100005]; const int M=1e9+7; int main() { int s=0,c=0,a=0,u=0,i;//s代表到該字元為止序列S的個數,c代表到該字元為止序列SC的個數,a代表到該字元為止序列SCA的個數,u代表到該字元為止SCAU的序列。 scanf("%s",ch); for(i=0; ch[i] != '\0'; i++) { if(ch[i] == 'S')//如果當前字元為S,那麼序列S的個數加一 s++; if(ch[i] == 'C')//如果當前字元為C,那麼序列SC的個數等於之前所求的SC的個數再加上該字元前S的個數 c =(c+s)%M; if(ch[i] == 'A')//如果當前字元為A,那麼序列SCA的個數等於之前所求的SCA的個數加上該字元前SC的個數 a =(a+c)%M; if(ch[i] == 'U')//如果當前字元為U,那麼序列SCAU的個數等於之前所求的SCAU的個數加上該字元前SCA的個數 u =(u+a)%M; } printf("%d",u); }
第一次提交wa了。。。原因竟是……!!忘記求模了。。。震撼我媽