标签:color int empty always pre data- first recently 通过
You should output the result modulo 10^9+7.
2 3 1 2 3 4 1 2 3 3
1 4
题意是 给n个数.
前面取随意个数 组成集合S 取在全部S中元素后面的随意个元素 T ,S 和T 不为空集;
计算能让S集合全部元素的异或(^)后得到的数等于 T集合全部元素与(&)后得到的数. 这样取两个集合,不同的取法有多少个.
data[ i ][ j ]表示在i号元素曾经,包含i, 能通过^运算得到j的方法数
data2[ i ][ j ]表示在i号元素以后,包含i,能通过&运算得到j的方法数
data3[ i ][ j ] 表示在i号元素以后,包含i,能通过&运算得到j,且一定取了i, 的方法数.
然后,不断递推,就能够了.
#include<stdio.h>
#include<string.h>
__int64 data[2000][1200],data2[2000][1200],data3[2000][1200];
int main()
{
int t,n,i,a[2000],j;
__int64 ans;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
memset(data,0,sizeof(data));
memset(data2,0,sizeof(data2));
memset(data3,0,sizeof(data3));
for(i=1;i<=n;i++)
{
if(i!=1)
{
for(j=0;j<1024;j++)
{
if(data[i-1][j])
{
data[i][j^a[i]]+=data[i-1][j];//取了当前这个
data[i][j^a[i]]%=(1000000000+7);
data[i][j]+=data[i-1][j];//没取当前这个
data[i][j]%=(1000000000+7);
}
}
}
data[i][a[i]]++;//仅仅取当前这个 前面的都没取
data[i][a[i]]%=(1000000000+7);
}
ans=0;
for(i=n;i>=1;i--)//data2 代表所有的 data3 代表取了当前这个的,避免反复计算
{
data3[i][a[i]]++;//仅仅取了当前这个
data3[i][a[i]]%=(1000000000+7);
data2[i][a[i]]++;
data2[i][a[i]]%=(1000000000+7);
if(i!=n)
{
for(j=0;j<1024;j++)
{
if(data2[i+1][j])
{
data2[i][j&a[i]]+=data2[i+1][j];//取了当前这个
data2[i][j&a[i]]%=(1000000000+7);
data3[i][j&a[i]]+=data2[i+1][j];
data3[i][j&a[i]]%=(1000000000+7);
data2[i][j]+=data2[i+1][j];//没取当前这个
data2[i][j]%=(1000000000+7);
}
}
}
for(j=0;j<1024;j++)
{
if(data3[i][j])
{
ans+=data[i-1][j]*data3[i][j];
ans=ans%(1000000000+7);
}
}
}
printf("%I64d\n",ans);
}
return 0;
}
hdu 4901 The Romantic Hero 计数dp,位计算
标签:color int empty always pre data- first recently 通过
原文地址:http://www.cnblogs.com/ljbguanli/p/6993269.html