题目链接

题意:给一个数组a,从中选择一些元素,构成两个数组s, t,使s数组里的所有元素异或

等于 t数组里的所有元素 位于,求有多少种构成方式。要求s数组里 的所有的元素的下标

小于 t数组里的所有的元素的下标。

分析:比赛的时候,刚开始脑子很乱,后来想了一下思路也敲了,发现自己的程序结果不对

自己一点一点计算后发现自己的程序有一部分计算重复了,其实还是dp的思路不够清晰。

d[i][j]代表第i个数 新产生的结果为数字 j 的个数。

AC代码:

 #include <iostream>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <cstdio>
#include <set>
#include <vector>
#include <algorithm>
#define LL long long
const int maxn = +;
const int mo = +;
using namespace std;
__int64 cnt;
int n, a[maxn];
__int64 d[maxn][maxn], dt[maxn][maxn], temp[maxn][maxn]; int main()
{
int T, i, j, x;
scanf("%d", &T);
while(T--)
{
cnt = ;
memset(d, , sizeof(d));
memset(dt, , sizeof(dt));
memset(temp, , sizeof(temp));
scanf("%d", &n);
for(i = ; i < n; i++)
scanf("%d", &a[i]);
for(i = ; i < n; i++)
{
for(j = ; j < ; j++)
{
if(i!= && temp[i-][j]) //让之前存在的和a[i]异或会产生新的存放在d数组里
{
x = (a[i]^j); //x有可能会大于j,所以不能用d数组直接累加
d[i][x] += temp[i-][j];
}
d[i][j] %= mo; //随时取余很重要,不然会wa
}
d[i][a[i]] ++; //加上自身
for(j = ; j < ; j++)
{
if(i != )
temp[i][j] += temp[i-][j] + d[i][j]; //temp数组用来维护目前所有的
else //结果,并且不可以用d直接加,否则会重复
temp[i][j] = d[i][j];
temp[i][j] %= mo;
}
}
memset(temp, , sizeof(temp));
for(i = n-; i >= ; i--)
{
for(j = ; j < ; j++)
{
if(temp[i+][j])
{
x = (a[i]&j);
dt[i][x] += temp[i+][j];
}
dt[i][j] %= mo;
}
dt[i][a[i]] ++;
for(j = ; j < ; j++)
{
temp[i][j] += temp[i+][j] + dt[i][j];
temp[i][j] %= mo;
}
}
for(i = n-; i >= ; i--)
for(j = ; j < ; j++)
{
dt[i][j] += dt[i+][j]; //这是防止重复的,让dt数组累加,d数组不累加。
dt[i][j] %= mo;
} for(i = ; i < n-; i++)
for(j = ; j < ; j++)
{
cnt += d[i][j]*dt[i+][j]; //用前面的乘以后面的
cnt %= mo;
}
cnt %= mo;
printf("%I64d\n", cnt);
}
return ;
}

顺便贴一下自己在比赛中wa的代码,思路不清。

 #include <iostream>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <cstdio>
#include <set>
#include <vector>
#include <algorithm>
#define LL long long
const int maxn = +;
const int mo = +;
using namespace std;
__int64 cnt, f[maxn];
int n, a[maxn];
__int64 d[maxn][maxn], dt[maxn][maxn]; int main()
{
int T, i, j, tmp;
scanf("%d", &T);
while(T--)
{
cnt = ;
memset(d, , sizeof(d));
memset(dt, , sizeof(dt));
memset(a, , sizeof(a));
memset(f, , sizeof(f));
scanf("%d", &n);
for(i = ; i < n; i++)
scanf("%d", &a[i]);
d[][a[]] = ;
f[a[]] = ;
for(i = ; i < n; i++)
{
for(j = ; j < ; j++)
{
if(f[j])
{
tmp = (a[i]^j);
d[i][tmp] += f[j];
}
d[i][j] %= mo;
}
d[i][a[i]] ++;
f[a[i]] ++;
} memset(f, , sizeof(f));
dt[n-][a[n-]] = ;
f[a[n-]] = ;
for(i = n-; i >= ; i--)
{
for(j = ; j < ; j++)
{
if(f[j])
{
tmp = (a[i]&j);
dt[i][tmp] += f[j];
}
d[i][j] %= mo;
}
dt[i][a[i]] ++;
f[a[i]] ++;
} for(i = n-; i >= ; i--)
for(j = ; j < ; j++)
{
dt[i][j] += dt[i+][j];
dt[i][j] %= mo;
} for(i = ; i < n-; i++)
for(j = ; j < ; j++)
{
cnt += d[i][j]*dt[i+][j];
cnt %= mo;
}
cnt %= mo;
printf("%I64d\n", cnt);
}
return ;
}

hdu 4901 The Romantic Hero (dp)的更多相关文章

  1. HDU 4901 The Romantic Hero(二维dp)

    题目大意:给你n个数字,然后分成两份,前边的一份里面的元素进行异或,后面的一份里面的元素进行与.分的时候依照给的先后数序取数,后面的里面的全部的元素的下标一定比前面的大.问你有多上种放元素的方法能够使 ...

  2. HDU 4901 The Romantic Hero (计数DP)

    The Romantic Hero 题目链接: http://acm.hust.edu.cn/vjudge/contest/121349#problem/E Description There is ...

  3. HDU 4901 The Romantic Hero 题解——S.B.S.

    The Romantic Hero Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

  4. HDU 4901 The Romantic Hero

    The Romantic Hero Time Limit: 3000MS   Memory Limit: 131072KB   64bit IO Format: %I64d & %I64u D ...

  5. 2014多校第四场1005 || HDU 4901 The Romantic Hero (DP)

    题目链接 题意 :给你一个数列,让你从中挑选一些数组成集合S,挑另外一些数组成集合T,要求是S中的每一个数在原序列中的下标要小于T中每一个数在原序列中下标.S中所有数按位异或后的值要与T中所有的数按位 ...

  6. HDU - 4901 The Romantic Hero(dp)

    https://vjudge.net/problem/HDU-4901 题意 给n个数,构造两个集合,使第一个集合的异或和等于第二个集合的相与和,且要求第一个集合的元素下标都小于第二个集合的元素下标. ...

  7. HDOJ 4901 The Romantic Hero

    DP....扫两次合并 The Romantic Hero Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 ...

  8. 【bzoj3866】The Romantic Hero dp

    题目描述 给你n个数,从中选出两个不相交非空集合S和T,使得S中的每一个元素都在T集合的前面,并且S集合中的所有数的亦或等于T集合中的所有数的与,求方案数 mod 10^9+7. 输入 The fir ...

  9. HDU4901 The Romantic Hero 计数DP

    2014多校4的1005 题目:http://acm.hdu.edu.cn/showproblem.php?pid=4901 The Romantic Hero Time Limit: 6000/30 ...

随机推荐

  1. 谁是最好的Coder

    谁是最好的Coder 时间限制:1000 ms  |  内存限制:65535 KB 难度:0   描述 计科班有很多Coder,帅帅想知道自己是不是综合实力最强的coder. 帅帅喜欢帅,所以他选了帅 ...

  2. JavaScript Tutorial

    JavaScript Tutorial http://javascript.info/root Object.create rabit.hasOwnProperty('eats') Object.ge ...

  3. .Net webservice动态调用

    直接贴代码吧 public class PmsService { /// <summary> /// pms接口 /// </summary> /// <param na ...

  4. Backbone.Events—纯净MVC框架的双向绑定基石

    Backbone.Events-纯净MVC框架的双向绑定基石 为什么Backbone是纯净MVC? 在这个大前端时代,各路MV*框架如雨后春笋搬涌现出来,在infoQ上有一篇 12种JavaScrip ...

  5. java集合类(五)About Map

    接上篇“java集合类(四)About Set” 这次学完Map之后,就剩队列的知识,之后有关java集合类的学习就将告一段落,之后可能会有java连接数据库,I/O,多线程,网络编程或Android ...

  6. CKFinder 1.4.3 任意文件上传漏洞

    CKFinder 是国外一款非常流行的所见即所得文字编辑器,其1.4.3 asp.net版本存在任意文件上传漏洞,攻击者可以利用该漏洞上传任意文件. CKFinder在上传文件的时候,强制将文件名(不 ...

  7. Unity GameObject.activeSelf, GameObject.activeInHierarchy,GameObject.SetActive和SetActiveRecursively

    activeSelf(read only只读):物体本身的active状态,对应于其在inspector中的checkbox是否被勾选activeInHierarchy(read only只读):物体 ...

  8. 初学tornado之MVC版helloworld

    作者:the5fire | 标签: MVC  tornado  | 发布:2012-08-06 2:41 p.m. 文接上篇,看我一个简单的helloworld,虽然觉得这个框架着实精小,但是实际开发 ...

  9. Stateless Iterators

    As the name implies, a stateless iterator is an iterator that does not keep any state by itself. The ...

  10. POJ2485Highways

    http://poj.org/problem?id=2485 题意 : 这道题和1258很像,但是这道题求的是最小生成树中最大的那条边,所以在函数里处理一下就行了. 思路 : 赤裸裸的最小生成树啊,但 ...