码迷,mamicode.com
首页 > 其他好文 > 详细

hdu4901

时间:2014-08-03 20:22:25      阅读:255      评论:0      收藏:0      [点我收藏+]

标签:blog   os   io   数据   for   代码   div   amp   

题意:有n个数(n<=1000),每个数<1024,现在给出a、b两个集合,需要你从这n个数中取出一些数,将取出的数放在a集合或者b集合,a集合的数的最大下标严格小于b集合所取的数的最小下标,然后a集合的数进行抑或操作,b集合的数进行与操作,问你操作后,这两个数相等,问你有多少种不同的方法。

思路:我发现暑假集训开始到现在,我一直在酱油中,状态根本没回升--以前遇到这样的题目,果断是可以出的,而在比赛的时候,还是队友提示,我才想到思路的。

其实,我们可以开个二维数组来记录在第i个数放入a集合时所取到的数的种数......与就是dp[1005][1024]

这样,不仅记录了在a集合取第i个数的时候,这个数是否存在,还记录了这个数存在的情况下,出现的次数。。。。。。

然后,我还开了个数组,记录b集合的。

这里需要注意,要将b集合的数据,全部集中到一起,而a集合的数据则不必,只需要再开一个数组,将a集合前面所有出现过的数以及次数保存下来,在去第i个数时,不仅

要判断i-1的情况,还要判断i-2,i-3,i-4.....1的所有情况,但是不能像b集合那样操作,将所有数据都集中在一起,那样会多的。

只能是再开一个数组,记录a集合i-1以前所有出现过的数据。

ac代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef __int64 ss;
const ss mod=1000000007;
int dp[1005][1080],t[1005][1080],n,s[1005],maxn;
int p[1005][1080];
/*
dp数组是用来记录a集合中与前i-1个数第i个数异或的结果以及次数

p数组,用来记录a集合中i-1之前出现的数的次数

t数组,用来记录b集合中i到n之间所有出现的结果以及次数,不与i异或,但
也出现了的结果,要是记录在t数组中
*/
int main()                   
{
    int text;
    scanf("%d",&text);
    while(text--)
    {
        memset(dp,0,sizeof(dp));
        memset(t,0,sizeof(t));
        memset(p,0,sizeof(p));
        scanf("%d",&n);
        maxn=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&s[i]);
            maxn|=s[i];
        }

        dp[1][s[1]]=1;
        t[n][s[n]]=1;
        p[1][s[1]]=1;
        for(int i=2;i<n;i++)
        {
            dp[i][s[i]]++;
            p[i][s[i]]++;
            p[i][s[i]]%=mod;
            dp[i][s[i]]%=mod;
            for(int j=0;j<=maxn;j++)
            {
                p[i][j]+=p[i-1][j];
                p[i][j]%=mod;
                if(dp[i-1][j])
                {
                    int tmp=j^s[i];
                    dp[i][tmp]+=dp[i-1][j];
                    p[i][tmp]+=dp[i-1][j];
                    p[i][tmp]%=mod;
                    dp[i][tmp]%=mod;
                }
                if(i-2>0)
                {
                    if(p[i-2][j])
                    {
                        ss tmp=j^s[i];
                        dp[i][tmp]+=p[i-2][j];
                        p[i][tmp]+=p[i-2][j];
                        p[i][tmp]%=mod;
                        dp[i][tmp]%=mod;
                    }
                }
            }
        }
        for(int i=n-1;i>1;i--)
        {
            t[i][s[i]]++;
            t[i][s[i]]%=mod;
            for(int j=0;j<=maxn;j++)
            {
                t[i][j]+=t[i+1][j];
                t[i][j]%=mod;
                if(t[i+1][j])
                {
                    ss tmp=s[i]&j;
                    t[i][tmp]+=t[i+1][j];
                    t[i][tmp]%=mod;
                }
            }
        }
        ss ans=0;
        for(int i=1;i<n;i++)
        {
            for(int j=0;j<=maxn;j++)
            {
                ans+=(((__int64)dp[i][j]*(__int64)t[i+1][j])%mod);
                ans%=mod;
            }
        }
        printf("%I64d\n",ans);
    }
    return 0;
}

  

hdu4901,布布扣,bubuko.com

hdu4901

标签:blog   os   io   数据   for   代码   div   amp   

原文地址:http://www.cnblogs.com/ziyi--caolu/p/3888670.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!