zoukankan      html  css  js  c++  java
  • SDUTOJ2879 Colorful Cupcakes(dp)

    山东省赛的一道题

    题意:

    聚会一个圆桌,相邻字母不能重复,有ABC三种字母

    问有多少种方法

    思路:

    dp

    第一维滚动,第二维ABC当前位置,后三维存ABC用的个数

    由于放在了UPCOJ上,判题比较慢,优化了一下,

    在SDUTIJ上20ms

    /* ***********************************************
    Author        :devil
    Created Time  :2016/5/14 17:19:27
    ************************************************ */
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <cmath>
    #include <stdlib.h>
    using namespace std;
    const int mod=1e9+7;
    int dp[2][3][27][27][27],a[3];
    int main()
    {
        //freopen("in.txt","r",stdin);
        int t;
        char s[51];
        scanf("%d",&t);
        while(t--)
        {
            scanf("%s",s);
            int l=strlen(s);
            a[0]=1,a[1]=1,a[2]=1;
            for(int i=0; i<l; i++)
                a[s[i]-'A']++;
            if(a[0]>a[1]) swap(a[0],a[1]);
            if(a[1]>a[2]) swap(a[1],a[2]);
            if(a[0]+a[1]<=a[2])
            {
                printf("0
    ");
                continue;
            }
            l+=3;
            long long ans=0;
            for(int y=0; y<3; y++)
            {
                memset(dp,0,sizeof(dp));
                if(y==0) dp[0][0][2][1][1]=1;
                else if(y==1) dp[0][1][1][2][1]=1;
                else dp[0][2][1][1][2]=1;
                int cur=0;
                for(int cnt=5; cnt<=l; cnt++)
                {
                    cur^=1;
                    for(int i=1; i<=min(a[0],cnt); i++)
                    {
                        for(int j=1; j<=min(a[1],cnt); j++)
                        {
                            int k=cnt-i-j;
                            if(k>a[2]) continue;
                            dp[cur][0][i][j][k]=dp[cur^1][1][i-1][j][k]+dp[cur^1][2][i-1][j][k];
                            if(dp[cur][0][i][j][k]>=mod) dp[cur][0][i][j][k]-=mod;
                            dp[cur][1][i][j][k]=dp[cur^1][0][i][j-1][k]+dp[cur^1][2][i][j-1][k];
                            if(dp[cur][1][i][j][k]>=mod) dp[cur][1][i][j][k]-=mod;
                            dp[cur][2][i][j][k]=dp[cur^1][1][i][j][k-1]+dp[cur^1][0][i][j][k-1];
                            if(dp[cur][2][i][j][k]>=mod) dp[cur][2][i][j][k]-=mod;
                        }
                    }
                }
                if(y==0) ans+=dp[cur][1][a[0]][a[1]][a[2]]+dp[cur][2][a[0]][a[1]][a[2]];
                else if(y==1) ans+=dp[cur][0][a[0]][a[1]][a[2]]+dp[cur][2][a[0]][a[1]][a[2]];
                else ans+=dp[cur][0][a[0]][a[1]][a[2]]+dp[cur][1][a[0]][a[1]][a[2]];
                while(ans>=mod) ans-=mod;
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    MapReduce Design Patterns(4. 分层,分区)(七)
    MapReduce Design Patterns(3. Top Ten))(六)
    MapReduce Design Patterns(3. Top Ten))(六)
    树的子结构-剑指Offer
    合并两个排序的链表-剑指Offer
    反转链表-剑指Offer
    链表中倒数第k个结点-剑指Offer
    数值的整数次方-剑指Offer
    二进制中1的个数-剑指Offer
    变态跳台阶-剑指Offer
  • 原文地址:https://www.cnblogs.com/d-e-v-i-l/p/5492969.html
Copyright © 2011-2022 走看看