hdu 5291 Candy Distribution(dp)

题目链接:hdu 5291 Candy Distribution

每次先计算出dp[0],然后根据dp[0]的数值可以用o(1)的复杂度算出dp[1],以此类推。总体复杂度为o(200 * 80000),可以接受。

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int maxn = 80000;
const int maxm = 205;
const int mod = 1e9+7;
#define coe(x) ((x)/2+1)

int N, M, A[maxm], dp[2][maxn + 5];

int query(int x, int now) {
	if (x < 0 || x > 2*M)
		return 0;
	return dp[now][x];
}

int solve () {
	int now = 0, pre = 1;
	memset(dp[now], 0, sizeof(dp[now]));

	dp[now][M] = 1;
	for (int i = 0; i < N; i++) {
		now = pre;
		pre = pre^1;
		int sumL = 0, sumR = 0, addL = 0, addR = 0;

		for (int k = -A[i]; k <= A[i]; k++) {
			int tmp = query(k, pre);
			dp[now][0] = 0;
			dp[now][0] = (dp[now][0] + 1LL * tmp * coe(A[i]-(k < 0 ? -k : k)) % mod) % mod;
			if (k <= 0) {
				sumL = (sumL + tmp) % mod;
				if ((k&1) == 0)
					addL = (addL + tmp) % mod;
			}

			if (k >= 0) {
				sumR = (sumR + tmp) % mod;
				if ((k&1) == 0)
					addR = (addR + tmp) % mod;
			}
		}

		if (A[i]&1) {
			addR = (sumR - addR + mod) % mod;
			addL = (sumL - addL + mod) % mod;
		}

		for (int k = 1; k <= M*2; k++) {
			sumR = (sumR + query(A[i] + k, pre)) % mod;
			addR = (sumR + mod - addR) % mod;
			sumR = (sumR + mod - query(k-1, pre)) % mod;

			dp[now][k] = ((dp[now][k-1] + addR - addL) % mod + mod) % mod;

			sumL = (sumL + query(k, pre)) % mod;
			addL = (sumL + mod - addL) % mod;
			sumL = (sumL + mod - query(k - A[i] - 1, pre)) % mod;
		}
	}
	return dp[now][M];
}

int main () {
	int cas;
	scanf("%d", &cas);
	while (cas--) {
		scanf("%d", &N);
		M = 0;
		for (int i = 0; i < N; i++) {
			scanf("%d", &A[i]);
			M += A[i];
		}
		printf("%d\n", solve());
	}
	return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-12 23:58:55

hdu 5291 Candy Distribution(dp)的相关文章

HDU 4960 (水dp)

Another OCD Patient Problem Description Xiaoji is an OCD (obsessive-compulsive disorder) patient. This morning, his children played with plasticene. They broke the plasticene into N pieces, and put them in a line. Each piece has a volume Vi. Since Xi

HDU 1087 &amp;&amp; POJ 2533(DP,最长上升子序列).

~~~~ 两道题的意思差不多,HDU上是求最长上升子序列的和,而POJ上就的是其长度. 貌似还有用二分写的nlogn的算法,不过这俩题n^2就可以过嘛.. ~~~~ 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1087 http://poj.org/problem?id=2533 ~~~~ HDU1087: #include<cstdio> #include<cstring> #include<algorithm> #

hdu 2296 aC自动机+dp(得到价值最大的字符串)

Ring Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3180    Accepted Submission(s): 1033 Problem Description For the hope of a forever love, Steven is planning to send a ring to Jane with a rom

hdu 2457 AC自动机+dp

DNA repair Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2004    Accepted Submission(s): 1085 Problem Description Biologists finally invent techniques of repairing DNA that contains segments c

Hdu 4465 Candy (快速排列组合+概率)

题目链接: Hdu 4465 Candy 题目描述: 有两个箱子,每个箱子有n颗糖果,抽中第一个箱子的概率为p,抽中另一个箱子的概率为1-p.每次选择一个箱子,有糖果就拿走一颗,没有就换另外一个箱子.问换箱子的时候,另外一个箱子中剩下糖果的期望值. 解题思路: 注意题目描述,其中任意一个箱子没有糖果,另一个箱子中剩下糖果个数的期望,而不是第一个箱子没有糖果.不是把其中一个箱子取空时,另一个箱子剩下糖果的期望,而是其中一个箱子取空再换另外一个箱子时,这个箱子的期望. 可以根据期望性质画出公式:an

[ACM] hdu 3555 Bomb (数位DP,统计1-N中含有“49”的总数)

Bomb Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 7187 Accepted Submission(s): 2512 Problem Description The counter-terrorists found a time bomb in the dust. But this time the terrorists impro

HDU 4833 Best Financing DP

Best Financing Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 120    Accepted Submission(s): 24 Problem Description 小 A想通过合理投资银行理财产品达到收益最大化.已知小A在未来一段时间中的收入情况,描述为两个长度为n的整数数组dates和earnings,表示在

hdu 1011(树形dp)

Mark.看着吴神博客写的,还未完全懂. 1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <algorithm> 5 #include <vector> 6 #include <queue> 7 #include <set> 8 #include <map> 9 #include <string>

HDU 2294 Pendant (DP+矩阵快速幂降维)

HDU 2294 Pendant (DP+矩阵快速幂降维) ACM 题目地址:HDU 2294 Pendant 题意: 土豪给妹子做首饰,他有K种珍珠,每种N个,为了炫富,他每种珍珠都要用上.问他能做几种长度[1,N]的首饰. 分析: 1 ≤ N ≤ 1,000,000,000简直可怕. 首先想dp,很明显可以想到: dp[i][j] = (k-(j-1))*dp[i-1][j-1] + j*dp[i-1][j](dp[i][j]表示长度为i的并且有j种珍珠的垂饰有多少个) 然后遇到N太大的话,