hdu 4901 The Romantic Hero (dp)
题意:给一个数组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)的更多相关文章
- HDU 4901 The Romantic Hero(二维dp)
题目大意:给你n个数字,然后分成两份,前边的一份里面的元素进行异或,后面的一份里面的元素进行与.分的时候依照给的先后数序取数,后面的里面的全部的元素的下标一定比前面的大.问你有多上种放元素的方法能够使 ...
- HDU 4901 The Romantic Hero (计数DP)
The Romantic Hero 题目链接: http://acm.hust.edu.cn/vjudge/contest/121349#problem/E Description There is ...
- 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 ...
- HDU 4901 The Romantic Hero
The Romantic Hero Time Limit: 3000MS Memory Limit: 131072KB 64bit IO Format: %I64d & %I64u D ...
- 2014多校第四场1005 || HDU 4901 The Romantic Hero (DP)
题目链接 题意 :给你一个数列,让你从中挑选一些数组成集合S,挑另外一些数组成集合T,要求是S中的每一个数在原序列中的下标要小于T中每一个数在原序列中下标.S中所有数按位异或后的值要与T中所有的数按位 ...
- HDU - 4901 The Romantic Hero(dp)
https://vjudge.net/problem/HDU-4901 题意 给n个数,构造两个集合,使第一个集合的异或和等于第二个集合的相与和,且要求第一个集合的元素下标都小于第二个集合的元素下标. ...
- HDOJ 4901 The Romantic Hero
DP....扫两次合并 The Romantic Hero Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 ...
- 【bzoj3866】The Romantic Hero dp
题目描述 给你n个数,从中选出两个不相交非空集合S和T,使得S中的每一个元素都在T集合的前面,并且S集合中的所有数的亦或等于T集合中的所有数的与,求方案数 mod 10^9+7. 输入 The fir ...
- HDU4901 The Romantic Hero 计数DP
2014多校4的1005 题目:http://acm.hdu.edu.cn/showproblem.php?pid=4901 The Romantic Hero Time Limit: 6000/30 ...
随机推荐
- UML类图总结
前言 类图和序列图是UML中最常用的两种Diagram.我将做详细的总结.在许多书中,或者网站中,在介绍一个系统的子系统的设计时,很多时候,都是给出简单的类图来简述构成子系统的类之间的关系.这足以说明 ...
- cocos2dx中的格子地图TileMap
格子地图的优点: a.节省内存,我们知道对于一款游戏来说,如果以图片来作为地图的话,对于神庙逃亡,魂斗罗这样的场景很多,地图很长的游戏显然不现实,因为图片很占内存,但是这些游戏的地图有一个特点就是:重 ...
- java多线程状态转换
http://www.mamicode.com/info-detail-517008.html 相关资料链接 我觉得下面这张图总结的很好
- IntelliJ IDEA 比较当前版本文件与历史文件
前言: 写代码修改后怎样比较与历史文件的区别呢?idea提供了2种比较方式(目前笔者所了解到的) 一.SVN的版本比较 二.当前文件与历史版本比较
- Jquery.linq 使用示例
http://linqjs.codeplex.com/ /*Linq JS*/ //range var aa = Enumerable.range(1, 10).toArray(); var kk = ...
- [bzoj 2159]Crash的文明世界
今天看到一个鬼题 心情好的时候写 [题意]求树上所有点对距离的k次方和,所有边权为1 大爷方的题解:http://tonyfang.is-programmer.com/posts/204972.htm ...
- nenu contest2
http://vjudge.net/vjudge/contest/view.action?cid=54562#overview H B. Polygons http://codeforces.com ...
- 【ACMER纷纷表示】女生应该找一个玩ACM的男生
1.强烈的事业心 将来,他也一定会有自己热爱的事业.而且,男人最性感的时刻之一,就是他专心致志做事的时候.所以,找一个机会在他全神贯注玩ACM的时候,从侧面好好观察他,你就会发现我说的话没错.2.永不 ...
- Windows 进程通信 之 DDE技术
DDE (Dynamic Data Exchange,DDE)动态数据交换,是一种进程间通信机制,它最早是随着Windows由微软提出的.当前大部分软件仍旧支持DDE,但最近十年里微软已经停止发展DD ...
- EXCEL,熟悉又不熟悉的项目管理工具
EXCEL,熟悉又不熟悉的项目管理工具 如何利用excel做轻量级的项目管理 教你用Excel进行项目管理