原题地址

对于给定的两个约束条件,可以通过联立方程组直接解出子序列A的和和子序列B的和,即sum(A) = (r + s) / 2,sum(B) = (r - s) / 2,假设|A|=|B|=n

所以问题变成了,在一个数组中求长度为n且子序列和为sum(A)或sum(B)有多少个。

假设count(n, s)表示长度为n且子序列和为s有多少个,则要求的是count(n, sum(A)) * count(n, sum(B)),其中1<=n<=m

或者通俗来说就是m个k-sum问题

求k-sum,如果用搜索的方法,时间复杂度大概是n^k量级(可以优化到n^(k - 1) + nlogn),何况现在要求的是m个k-sum问题,即使排序+剪枝优化肯定也会超时(别问我是怎么知道的

所以只能选择动归,因为每次求k-sum的过程存在大量重复计算。

令f[i][j][k]表示从第i个元素开始,子序列长度为j,子序列和为k,这样的子序列有多少个

那么有地推公式:f[i][j][k] = f[i+1][j - 1][k - a[i]] + f[i + 1][j][k]

这个公式其实挺straightforward,跟背包问题是一样的。

由于sum(A)和sum(B)最大不过2000,所以k的范围是2000,另外i和j的范围分别是m的范围100,所以如果不做任何状态压缩,占用空间大概是2000*100*100*4*8约为640MB(用int存储),显然要爆。所以还必须状态压缩。

分析地推公式,明显压缩i那维,而且不难看出j和k必须从后向前推。还是跟背包问题一样。

代码:

 #include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std; #define MAX_SIZE 128
#define MAX_SUM 2048
#define MOD 1000000007 long long a[MAX_SIZE];
int m, r, s;
long long f[MAX_SIZE][MAX_SUM]; int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int sa, sb;
long long res = ; cin >> m >> r >> s;
sa = (r + s) / ;
sb = (r - s) / ;
for (int i = ; i < m; i++)
cin >> a[i]; memset(f, , sizeof(f));
f[][] = ;
for (int i = m - ; i >= ; i--) {
for (int j = m; j >= ; j--) {
for (int k = ; k >= ; k--) {
if (k >= a[i])
f[j][k] = (f[j][k] + f[j - ][k - a[i]]) % MOD;
}
}
} for (int i = ; i <= m; i++)
res = (res + (f[i][sa] * f[i][sb]) % MOD) % MOD; cout << res << endl;
return ;
}

第一次用的int,结果提交以后有些case是WA,考虑到DP问题基本上不会出现WA的情况,所以断定应该是数据溢出了,换成long long果然就没问题了。

HackerRank# Wet Shark and Two Subsequences的更多相关文章

  1. 【CodeForces 621A】Wet Shark and Odd and Even

    题 Today, Wet Shark is given n integers. Using any of these integers no more than once, Wet Shark wan ...

  2. 【CodeForces 621C】Wet Shark and Flowers

    题 There are n sharks who grow flowers for Wet Shark. They are all sitting around the table, such tha ...

  3. Wet Shark and Flowers(思维)

    C. Wet Shark and Flowers time limit per test 2 seconds memory limit per test 256 megabytes input sta ...

  4. B. Wet Shark and Bishops(思维)

    B. Wet Shark and Bishops time limit per test 2 seconds memory limit per test 256 megabytes input sta ...

  5. cf-A. Wet Shark and Odd and Even(水)

    A. Wet Shark and Odd and Even time limit per test 2 seconds memory limit per test 256 megabytes inpu ...

  6. Codeforces 612B. Wet Shark and Bishops 模拟

    B. Wet Shark and Bishops time limit per test: 2 seconds memory limit per test: 256 megabytes input: ...

  7. Codeforces Round #341 (Div. 2) E. Wet Shark and Blocks dp+矩阵加速

    题目链接: http://codeforces.com/problemset/problem/621/E E. Wet Shark and Blocks time limit per test2 se ...

  8. Wet Shark and Bishops(思维)

    Today, Wet Shark is given n bishops on a 1000 by 1000 grid. Both rows and columns of the grid are nu ...

  9. 【38.24%】【codeforces 621E】 Wet Shark and Blocks

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

随机推荐

  1. android开发学习 ------- 【转】Genymotion 小白安装

    参考 https://www.cnblogs.com/whycxb/p/6850454.html 很详细,全面

  2. JVM初探

    ### JVM分为类的加载生命周期和gc垃圾回收两个大的方面#####首先是类的生命周期, 类的加载: --> 记载字节码 ---> 这个过程有类的加载起参与,双亲委托机制() --> ...

  3. [转]IntelliJ IDEA 自定义方法注解模板

    IntelliJ IDEA 自定义方法注解模板 置顶2017年08月02日 18:04:36 阅读数:32592 最近没啥事开始正式用Eclipse 转入 idea工具阵营,毕竟有70%的开发者在使用 ...

  4. 移动端1px边框伪类宽高计算

    移动端1px边框在手机上看显得比较粗,于是我们用伪类结合css3缩放的方法去设置线条,但是如果设置div的一条边,水平线就设置宽度100%,垂直线就设置高度100%,那么如果是div的四条边呢?宽高1 ...

  5. Java网络编程学习笔记

    Java网络编程,我们先来看下面这一张图: 由图可得:想要进行网络编程,首先是服务器端通过ServerSocket对某一个端口进行监听.通过accept来判断是否有客户端与其相连.若成功连上,则通过r ...

  6. 版本号比较versioncompare方法,java实现

    测试

  7. 判断空间上三个点是否共线问题【找bug篇】

    判断空间上三个点是否在同一直线上[找bug篇] 作者:Vashon 时间:20150601   发布时间:20150718 一.拿到问题,首先分析并理清思路. 判断三点是否在同一条直线上需满足以下几点 ...

  8. CentOS下JRE环境变量配置

    很多时候,我们需要在CentOS上部署tomcat,从而搭建web服务器,然JDK/JRE环境是前提,这里就记录一下,在后面的时候直接使用. 下载jre-7u80-linux-x64.tar.gz,并 ...

  9. 洛谷 P1413 坚果保龄球

    题目描述 PVZ这款游戏中,有一种坚果保龄球.zombie从地图右侧不断出现,向左走,玩家需要从左侧滚动坚果来碾死他们. 我们可以认为地图是一个行数为6,列数为60的棋盘.zombie出现的那一秒站在 ...

  10. mysql登录(linux)

    一.修改配置文件 查询路径 find / -name my.cnf 修改文件 vi my.cnf [mysqld]下面加上skip-grant-tables 二.登录数据库 重启mysql servi ...