1. 程式人生 > >再入DP:尋找SCAU

再入DP:尋找SCAU

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了。。。原因竟是……!!忘記求模了。。。震撼我媽