hdu 1502 Regular Words(DP)

题意:

一个单词X由{A,B,C}三种字母构成。

A(X):单词X中A的个数。B(X),C(X)同理。

一个单词X如果是regular word必须满足A(X)=B(X)=C(X)且对于X的任意前缀有A(X)>=B(X)>=C(X)。

给一个数n。问长度为3n的regular word有多少个。

思路:

dp[a][b][c]:前a+b+c个字母由a个A,b个B,c个C构成。

然后就可以分解了,,,

*:用到高精度

代码:

int const MAXN=99999999;
int const DLEN=8;

class BigNum{
private:
    int a[20];
    int len;
public:
    BigNum(){};
    BigNum(const int);
    BigNum &operator=(const BigNum &);
    BigNum operator+(const BigNum &) const;
    void print();
};

BigNum::BigNum(const int b){
    int c,d=b;
    len=0;
    mem(a,0);
    while(d>MAXN){
        c=d-(d/(MAXN+1))*(MAXN+1);
        d=d/(MAXN+1);
        a[len++]=c;
    }
    a[len++]=d;
}

BigNum & BigNum::operator=(const BigNum & n){
    int i;
    len=n.len;
    mem(a,0);
    rep(i,0,len-1) a[i]=n.a[i];
    return *this;
}

BigNum BigNum::operator+(const BigNum & T) const{
    BigNum t(*this);
    int i,big;
    big=T.len>len?T.len:len;
    for(int i=0;i<big;++i){
        t.a[i]+=T.a[i];
        if(t.a[i]>MAXN){
            t.a[i+1]++;
            t.a[i]-=(MAXN+1);
        }
    }
    if(t.a[big]!=0) t.len=big+1; else t.len=big;
    return t;
}

void BigNum::print(){
    int i;
    cout<<a[len-1];
    for(i=len-2;i>=0;i--){
        cout.width(DLEN);
        cout.fill(‘0‘);
        cout<<a[i];
    }
    cout<<endl;
}

int n;
BigNum dp[62][62][62];

int main(){

    int n;
    while(scanf("%d",&n)!=EOF){
        mem(dp,0);
        dp[0][0][0]=BigNum(1);

        rep(a,0,n){
            rep(b,0,n){
                rep(c,0,n){
                    if(a==0 && b==0 && c==0) continue;
                    if(a>=b && b>=c){
                        if(a-1>=b && a>=1){
                            dp[a][b][c]=dp[a][b][c]+dp[a-1][b][c];
                        }
                        if(b-1>=c && b>=1){
                            dp[a][b][c]=dp[a][b][c]+dp[a][b-1][c];
                        }
                        if(c>=1){
                            dp[a][b][c]=dp[a][b][c]+dp[a][b][c-1];
                        }
                    }
                }
            }
        }
        dp[n][n][n].print();
        printf("\n");
    }

    return 0;
}
时间: 2024-10-14 04:35:38

hdu 1502 Regular Words(DP)的相关文章

HDU 4745 Two Rabbits(DP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4745 题意:n个数排成一个环.两个人AB初始时各自选定一个位置.每一轮A在顺时针方向选择一个位置,B在逆时针选择一个位置,且这两个人所选位置的数字相等,然后格子跳到新选的位置上.问最多进行多少轮?有一个限制为每次跳跃不能跨过以前自己曾经选过的格子. 思路:主要是分析问题的本质.其实就是求最长回文子列.f[i][j]为[i,j]的最长回文子列,则答案为max(f[1][i],f[i+1][n]). i

HDU 4833 Best Financing (DP)

Best Financing Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 29    Accepted Submission(s): 3 Problem Description 小A想通过合理投资银行理财产品达到收益最大化.已知小A在未来一段时间中的收入情况,描述为两个长度为n的整数数组dates和earnings,表示在第dat

HDU 1260:Tickets(DP)

Tickets Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 923    Accepted Submission(s): 467 Problem Description Jesus, what a great movie! Thousands of people are rushing to the cinema. However,

hdu 1421 搬寝室 (dp)

思路分析: dp[i][j] 表示选取到第 i 个   组成了 j 对的最优答案. 当然排序之后 选取相邻两个是更优的. if(i==j*2) dp[i][j] = dp[i-2][j-1] + w[i]-w[i-2]^2.. else if( i> j*2 ) dp[i][j] = min (dp[i-2][j-1] + ...^2   ,    dp[i-1][j]).... #include <cstdio> #include <iostream> #include &

HDU 1159——Common Subsequence(DP)

Common Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 23279    Accepted Submission(s): 10242 Problem Description A subsequence of a given sequence is the given sequence with some e

HDU 3237 Help Bubu(DP)

题目链接:点击打开链接 思路: 比赛时查一点出, 需要加一个优化才能防止超时(恶心), 状态很容易想到: d[i][j][s][k]表示前i本书拿了j本没拿的书的集合是s没拿的书的最后一本是k的最优解. 为什么状态压缩的是目前桌子上的书的集合呢?  因为我们要防止一种情况:那就是如果对于高度为H的一种书, 我们都拿走了, 那么还要放回桌子上, 最优解要+1, 这样表示之后, 我们只要判断一下有几种书桌子上没有就行了. 细节参见代码: #include <cstdio> #include <

HDU 5791:Two(DP)

http://acm.hdu.edu.cn/showproblem.php?pid=5791 Two Problem Description Alice gets two sequences A and B. A easy problem comes. How many pair of sequence A' and sequence B' are same. For example, {1,2} and {1,2} are same. {1,2,4} and {1,4,2} are not s

hdu 1176 免费馅饼(DP)

题意: 都说天上不会掉馅饼,但有一天gameboy正走在回家的小径上,忽然天上掉下大把大把的馅饼.说来gameboy的人品实在是太好了,这馅饼别处都不掉,就掉落在他身旁的10米范围内.馅饼如果掉在了地上当然就不能吃了,所以gameboy马上卸下身上的背包去接.但由于小径两侧都不能站人,所以他只能在小径上接.由于gameboy平时老呆在房间里玩游戏,虽然在游戏中是个身手敏捷的高手,但在现实中运动神经特别迟钝,每秒种只有在移动不超过一米的范围内接住坠落的馅饼. 为了使问题简化,假设在接下来的一段时间

hdu 2189 来生一起走(DP)

题意: 有N个志愿者.指挥部需要将他们分成若干组,但要求每个组的人数必须为素数.问不同的方案总共有多少.(N个志愿者无差别,即每个组的惟一标识是:人数) 思路: 假设N个人可分为K组,将这K组的人数从小到大排序,num1,...,numk. 故N个人分组的方案数dp[n]=sum(dp[numk]) (所有分为K组的不同方案的和) 代码: bool yes[155]; int prime[155]; int dp[155]; int main(){ mem(yes,true); int C =