csuoj 1354: Distinct Subsequences

这个题是计算不同子序列的和;

spoj上的那个同名的题是计算不同子序列的个数;

其实都差不多;

 

计算不同子序列的个数使用dp的思想;

从头往后扫一遍

如果当前的元素在以前没有出现过,那么dp[i]=dp[i-1]*2+1;

不然找到最右边的这个元素出现的位置j;

dp[i]=d[i]*2-dp[j];

 

spoj代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#define mod 1000000007
using namespace std;

char s[100005];
int pos[100005];
int biao[30];
int dp[100005];

int main()
{
    int t,n;
    scanf("%d",&t);
    while(t--)
    {
        memset(biao,0,sizeof biao);
        scanf("%s",s+1);
        n=strlen(s+1);
        for(int i=1; i<=n; i++)
        {
            pos[i]=biao[s[i]-'A'];
            biao[s[i]-'A']=i;
        }
        dp[0]=0;
        for(int i=1; i<=n; i++)
        {
            if(pos[i]==0)
            {
                dp[i]=(dp[i-1]*2+1);
                while(dp[i]>=mod)dp[i]-=mod;
            }
            else
            {
                dp[i]=(dp[i-1]*2-dp[pos[i]-1]);
                if(dp[i]<0)dp[i]+=mod;
                while(dp[i]>=mod)dp[i]-=mod;
            }
        }
        printf("%d\n",dp[n]+1);
    }
    return 0;
}
View Code

 

csuoj代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#define mod 1000000007
using namespace std;
 
char s[100005];
int pos[100005];
int biao[15];
int dp[100005];
long long sum[100005];
 
int main()
{
    int t,n;
    scanf("%d",&t);
    while(t--)
    {
        memset(biao,0,sizeof biao);
        scanf("%s",s+1);
        n=strlen(s+1);
        for(int i=1; i<=n; i++)
        {
            pos[i]=biao[s[i]-'0'];
            biao[s[i]-'0']=i;
        }
        dp[0]=0;
        for(int i=1; i<=n; i++)
        {
            long long tmp=sum[i-1];
            if(pos[i]==0)
            {
                dp[i]=dp[i-1]*2;
                if((s[i]-'0')>0)dp[i]+=1;
                while(dp[i]>=mod)dp[i]-=mod;
            }
            else
            {
                dp[i]=(dp[i-1]*2-dp[pos[i]-1]);
                tmp-=sum[pos[i]-1];
                if(tmp<0)tmp+=mod;
                if(dp[i]<0)dp[i]+=mod;
                while(dp[i]>=mod)dp[i]-=mod;
            }
            sum[i]=(tmp*10+(long long)(dp[i]-dp[i-1])*(s[i]-'0')+sum[i-1])%mod;
            if(sum[i]<=0)sum[i]+=mod;
        }
        printf("%lld\n",sum[n]);
    }
    return 0;
}
View Code

 

posted @ 2013-12-11 22:47  Yours1103  阅读(162)  评论(0编辑  收藏  举报