51nod1202-递推&规律

来源:互联网 发布:电子处方软件 编辑:程序博客网 时间:2024/05/17 23:58

计数dp
记得减去空集。。。

#include <iostream>#include <cstdio>#include <cstring>/*我觉得我该学一下 组合数学了。。规律就是如果包含空集的话,那么dp[i]=dp[i-1]*2;//1个元素是俩,空集和本身当长度为i时,总共 pow(2,i) 并且每一个元素占 pow(2,i-1)个。*/using namespace std;typedef long long ll;const int maxn=1000006;const ll mod=1000000007;ll dp[maxn];int mark[maxn];int a[maxn];int main(){   int m ;    while(~scanf("%d",&m)){    for(int i=1;i<=m;i++){        scanf("%d",&a[i]);    }    memset(mark,0,sizeof(mark));    memset(dp,0,sizeof(dp));    dp[0]=1;    //mark[a[1]]=1;    //printf("%lld\n",mod);    for(int i=1;i<=m;i++){        if(!mark[a[i]])         {dp[i]=(dp[i-1]*2)%mod;mark[a[i]]=i;        // cout<<dp[i]<<endl;         }         else{            dp[i]=((dp[i-1]*2)%mod-(dp[mark[a[i]]-1]+mod)%mod)%mod;            mark[a[i]]=i;         }    }    dp[m]--;    /*for(int i=1;i<=m;i++)        printf("%lld\n",dp[i]);*/    printf("%lld\n",(dp[m]+mod)%mod);    }     return 0;}
原创粉丝点击