2015 whu校赛f题big data(dp + 小技巧)

题意是给定五个数n(n <= 100),a,b,l,r 另外有函数序列f(x),其中f(x + 1) = f(x) + a或f(x)+ b,f(0) = 0,问有多少个这样的函数序列f(1)到f(n)使得函数序列的和在l和r之间

解题思路如下:

图片有一处错误,要减去的是a*(n + 1) * n而不是 (b - a)* (n + 1) * n,此外,要注意x/c时向上取整和向下取整的问题。

这道题做做停停一个月了今天终于找时间ac了,有点感人呐

代码如下:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<map>
#include<set>
using namespace std;
#define LL long long  

const LL maxn = 100 + 5;
const LL INF = 0x3f3f3f3f;
LL d[(maxn + 1) * maxn / 2];
//freopen("input.txt", "r", stdin);

void solve(int n) {
	memset(d, 0, sizeof(d)); d[0] = 1;
	for(int i = 1; i <= n; i++) {
		for(int j = (i + 1) * i / 2; j >= i; j--)
			if(d[j] + d[j - i] > 1000000000000000000) d[j] = (d[j] + d[j - i]) % 1000000007;
			else d[j] = d[j] + d[j - i];
	}
}

int main() {
	int n, a, b, L, R;
	while(scanf("%d", &n) == 1) {
		scanf("%d%d%d%d", &a, &b, &L, &R);
		if(b != a) {
			if(b < a) swap(a, b);
			float xl = ceil( (float)(L - a*n*(n+1)/2) / (float)(b - a) ), xr = floor( (float)(R - a*n*(n+1)/2) / (float)(b - a) );
			//ceil函数向上取整,floor函数向下取整
			solve(n);
			LL ans = 0;
			if(xl < 0) xl = 0; if(xr > n*(n+1)/2) xr = n*(n+1)/2;
			for(int i = xl; i <= xr; i++)
				if(ans + d[i] > 1000000000000000000) ans = (ans + d[i]) % 1000000007;
				else ans += d[i];
		//	for(int i = xl; i <= xr; i++) printf("%lld\n", d[i]);
			printf("%d\n", ans % 1000000007);
		//	printf("%lld", d[0]);
		}
		else {
			int xl = (L - a*n*(n+1)/2), xr = (R - a*n*(n+1)/2);
			LL ans = 1;
			if(0 <= xr && 0 >= xl){
				for(int i = 1; i <= n; i++)
					ans = (ans * 2) % 1000000007;
				printf("%d\n", ans);
			}
			else printf("0\n");
		}
	}
	return 0;
}
时间: 2024-10-22 08:04:01

2015 whu校赛f题big data(dp + 小技巧)的相关文章

hust校赛 f题 The tree of hust(lis 变形)

题目大意是给出一段数字序列,可以忽略一次一段连续的序列,求忽略后的最长连续上升子序列 思路是dp,用end数组记录以当前元素作为结尾的最长连续上升序列的元素个数,那么不难得到状态转移方程为 dp(i) = max(dp(i - 1),  max( end[k] ) ) + 1 代码如下: #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostr

hdu 5475 模拟计算器乘除 (2015上海网赛F题 线段树)

给出有多少次操作 和MOD 初始值为1 操作1 y 表示乘上y操作2 y 表示除以第 y次操作乘的那个数 线段树的叶子结点i 表示 第i次操作乘的数 将1替换成y遇到操作2 就把第i个结点的值 替换成1利用线段树的性质,对整个1~n的区间进行维护,每次输出sum[1]的值即可 Sample Input110 10000000001 22 11 21 102 32 41 61 71 122 7 Sample OutputCase #1:2122010164250484 1 # include <i

HDU OJ 5317 RGCDQ( 2015多校联合训练第3场) 暴力+小技巧

题目连接:戳ME 题意:在一个[L,R]内找到最大的gcd(f[i],f[j])其中L<=i<j<=R,f[x]表示i分解质因数后因子的种类数.eg:f[10]=2(10=2*5),f[12]=2(12=2*2*3). 分析:很容易想到先将f[x]求出来,这里x最大1e6,要在常数时间内求出f[x].并且稍加分析就知道1<=f[x]<=7,可以用一个dp[i][j]表示从f[1]到f[i]有多少个j.这样就可以在常数时间内预处理出来,后面在O(1)的时间内就可以输出结果.并且

CSU 1425 NUDT校赛 I题 Prime Summation

这个题本来有希望在比赛里面出了的 当时也想着用递推 因为后面的数明显是由前面的推过来的 但是在计算的时候 因为判重的问题 ...很无语.我打算用一个tot[i]来存i的总种树,tot[i]+=tot[j]//j为可以由j推到i的一系列数,但这样是不对的,会产生大量重复计算... 看了下标程才发现要用二维来计算出种类总数,f[i][j]+=sum(f[i-j][k]) 表示在推i数的时候,第一个素数为j的种类数,注意j一定为素数,而且k不能大于j...标程里面处理的比较简练,就学了下他的写法. 至

2015北京网络赛A题The Cats&#39; Feeding Spots

题意:给你一百个点,找个以这些点为中心的最小的圆,使得这个圆恰好包含了n个点,而且这个圆的边界上并没有点 解题思路:暴力枚举每个点,求出每个点到其他点的距离,取第n大的点,判断一下. 1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 #include<iostream> 5 #include<memory.h> 6 using namespace std; 7 const i

北邮校赛 F. Gabriel&#39;s Pocket Money(树状数组)

F. Gabriel's Pocket Money 2017- BUPT Collegiate Programming Contest - sync 时间限制 2000 ms 内存限制 65536 KB 题目描述 For centuries, Heaven has required its young angels to live and study among humans in order to become full-fledged angels. This is no different

2015.4 校赛回顾

用了一下午时间重刷了一次校赛题目 不参考资料做的还是2333 第一题手速题 第二题 一开始取余运算少加了一个,WA了一发 #include<iostream> #include<cstdio> #include<cstring> using namespace std; int main() { int i,d[20000]; string c; memset(d,0,sizeof(d)); while(cin>>c) { int n=0; for(i=0;

2015 GDUT校赛

周末打了个GDUT的校赛,也是作为SCAU的一场个人排位. 比赛中竟然卡了个特判,1个半钟就切了5条了,然后一直卡. 还有其他两条可以做的题也没法做了,性格太执着对ACM来说也是错呀. 讲回正题 . A  游戏王 . 目的是集齐6张卡, 然后n个小伙伴手上持有卡num, 给出m种集合 , Stubird需要有某个集合中的卡片才能用c的花费去买这张卡片. 做法是状压dp , 开一个 dp[st] , 表示st( 0 <= st < (1<<6) ) 这个集合最小花费 . 然后开一个邻

PKU2018校赛 H题 Safe Upper Bound

http://poj.openjudge.cn/practice/C18H 题目 算平均数用到公式\[\bar{x}=\frac{x_1+x_2+x_3+\cdots+x_n}{n}\] 但如果用int型计算,那么\(x_1+x_2+x_3+\cdots+x_n\)可能会超过\(2^{31}-1\) 算6个数的平均数可以这么算 Calculate the average of\(x_1,x_2,x_3\)\[\bar{x}_1=\frac{x_1+x_2+x_3}{3}\]Calculate t