SDUT Mountain Subsequences 2607 dp(字母表优化) 2013年山东acm省赛

点击打开链接

题意给n让n个字母,求该串中存在多少个 a1 < ...< ai < ai+1 < Amax > aj > aj+1 > ... > an的情况



思路,枚举最大值,然后dp以s[i]为最大值,从前往后的逐渐增大的序列的个数,
这里用到了字母表的优化,由该题得出,此题不可以是n*n的时间复杂度,
所以要想到优化,如何优化呢,此时用的了字母本身,将每个字母在当前对应的个数进行保存,
然后枚举s[i]的字典序之前的加起来就行了


善于用题目中的条件,数学模型的建立
#include<bits/stdc++.h>
#define LL long long
using namespace std;
#define eps 1E-10
#define INF 0x3f3f3f3f

int di[100010],dj[100010];
int vi[100],mi[100];
char s[1000010];
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        scanf("%s",s);
        memset(di,0,sizeof(di));
        memset(vi,0,sizeof(vi));

        memset(dj,0,sizeof(dj));
        for(int i=0;i<n;i++)
        {
            int biao=s[i]-'a';
            for(int j=0;j<biao;j++)
            {
                di[i]=(di[i]+vi[j])%2012;
            }
            vi[biao]=(vi[biao]+di[i]+1)%2012;///本身单个字母自己就站一个位置所以加1。
        }
        memset(vi,0,sizeof(vi));


        for(int i=n-1;i>=0;i--)
        {
            int biao=s[i]-'a';   ///二维枚举字母,加上字典序之前的数量就可以了
            for(int j=0;j<biao;j++)
            {
                dj[i]=(dj[i]+vi[j])%2012;
            }
            vi[biao]=(vi[biao]+dj[i]+1)%2012;///本身单个字母自己就站一个位置所以加1。
        }
        LL sum=0;
        for(int i=0;i<n;i++)
        {
            ///cout<<di[i]<<" "<<dj[i]<<endl;
            sum=(sum+di[i]*dj[i])%2012;
        }
        printf("%lld\n",sum);
    }
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值