原题地址

对于给定的两个约束条件,可以通过联立方程组直接解出子序列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. Windows下Apache应用环境塔建安全设置(目录权限设置)

    目的:为Apache,php配置受限制的用户权限.保护系统安全.需要的朋友可以参考下. 环境配置情况: apache安装目录:d:\www-s\apache php目录:d:\www-s\php5 m ...

  2. AJPFX总结java InputStream读取数据问题

    1. 关于InputStream.read()     在从数据流里读取数据时,为图简单,经常用InputStream.read()方法.这个方法是从流里每次只读取读取一个字节,效率会非常低.     ...

  3. ImageView控件

    ImageView   显示图片 常用属性: src    要显示的图片 foreground 前景图 backgrund 背景图 alpha 透明度 clickable 是否可以点击 onClick ...

  4. subprocess模块详解2

    1.call() 和run功能类似,都是接受一个列表里的参数. >>> import subprocess >>> a = subprocess.call([&qu ...

  5. [BZOJ3527][ZJOI2014]力 FFT+数学

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3527 首先卷积的形式是$h(i)=\sum_{i=0}^jf(i)g(i-j)$,如果我们 ...

  6. 激活eclipse自动提示功能

    eclipse设置: Window->Preferences->Java->Editor->Content Assist

  7. tween.js下面的轮播(饿了么点餐的那种效果)

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  8. 一个简单的139邮箱登录脚本--->java-selenium

    import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebE ...

  9. learnpythonthehardway EX41 相关

    str.count() # str.count()方法用于统计字符串里某个字符出现的次数.可选参数为在字符串搜索的开始与结束位置. # str.count(sub, start= 0,end=len( ...

  10. Linux目录结构及详细介绍

    /:根目录,位于Linux文件系统目录结构的顶层,一般根目录下只存放目录,不要存放文件,/etc./bin./dev./lib./sbin应该和根目录放置在一个分区中. /bin,/usr/bin:该 ...