HDU 5230 ZCC loves hacking 大数字的整数划分
http://acm.hdu.edu.cn/showproblem.php?pid=5230
把题目简化后,就是求
1---n - 1这些数字中,将其进行整数划分,其中整数划分中不能有重复的数字,如果有这样的划分并且那个数字在[L, R]区间中,那么就算做一个贡献。
以前的整数划分,一般就是dp[i][j]表示i这个数字,最小的拆分数是j的时候,拥有的方案数,可以控制其没有重复数字,但是空间复杂度太大。
用一种新的方法
dp[i][j]表示j这个数字,当前的拆分拥有i个拆分数时的方案数。至于为什么要在第二维中放j这个数字,而不是像上面那个用第一维放数字,那是因为它需要先解出dp[1][1---n]然后再解出dp[2][1---n],转换维度比较方便。
先考虑允许重复数字 : dp[i][j] = dp[i][j - i] + dp[i - 1][j - 1];
考虑分成两类,
1、dp[i][j - i]:这种拆分方案(拥有i个数字的拆分方案),如果没有1,就比如7 = 3 + 4这样,然后每个数字都加上一,
就变成了9 = 5 + 4。所以dp[2][9]可以由dp[2][7]转化过来。当然7 = 1 + 6也是合法解。
2、dp[i - 1][j - 1]:这种拆分方案有1,比如4 = 3 + 1,那么我可以截去那个1,变成3 = 3,然后加上最后那个1,就变成了
4 = 3 + 1,所以dp[2][4]可以由dp[1][3]转化过来。
但是题目需要不重复,(这也使得题目不会超时)
第一类,如果dp[2][7]本来就是不重复的,就是dp[2][6]即是6 = 3 + 3不能发生,那么我同时全部加上一个数,肯定不会产生重复
的。
第二类,如果本来也是不重复的,但是生成的可能会重复,比如5 = 4 + 1和5 = 3 + 2是dp[2][5]的解(本来没有重复),然后在后面加上一个1,是dp[3][6]的解,但是6 = 4 + 1 + 1是非法的。我们也不可能检查其拆分方案有没1,因为我们只会统计数量。
改进
dp[i][j] = dp[i][j - i] + dp[i - 1][j - i];
dp[i - 1][j - i]:意思就是每个元素减去1后,分成i - 1组,为什么不是分成i组呢。?因为其存在1,然后每个数字减去1,那么这个1就是变成0了,所以只能分成i - 1组。
例如:6 = 3 + 2 + 1是由3 = 2 + 1弄过来的,dp[3][6] = dp[2][3]
所以就能解决这题。
1、i > j,不用管dp[i][j] = 0
2、i == j,只能够是i个1,然而不符合题目,dp[i][j] = 0;
3、i < j,dp[i][j] = dp[i][j - i] + dp[i - 1][j - i];
由于之和上一维有关,可以滚动数组,就能解决空间问题。
然后因为要产生k个不同的数字,最小值是1 + 2 + 3 + ..... + k,就是(1 + k) * k / 2开始。
就是dp[2][2]这些不用枚举了,k = 2的话,最小值是3
初始条件 dp[0][0] = 1;
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
const int MOD = ;
const int maxn = + ;
int dp[][maxn];
void work() {
int n, c, L, R;
scanf("%d%d%d%d", &n, &c, &L, &R);
if (c > R) {
printf("0\n");
return;
}
L = L - c;
R = R - c;
int ans = L == ; //c自己是一个
memset(dp, , sizeof dp);
dp[][] = ;
int now = ;
int all = ;
for (int i = ; i <= R; ++i) { //枚举拆分成i个,最多拆分成(i + 1) * i / 2个。
if (i * (i + ) / > R) break; //超越分数了
for (int j = (i + ) * i / ; j <= R; ++j) {
dp[now][j] = (dp[now][j - i] + dp[!now][j - i]) % MOD;
if (j >= L && j <= R) {
ans += dp[now][j];
ans %= MOD;
}
}
memset(dp[!now], , sizeof dp[!now]);
now = !now;
}
printf("%d\n", ans);
} int main() {
#ifdef local
freopen("data.txt","r",stdin);
#endif
int t;
scanf("%d", &t);
while (t--) work();
return ;
}
HDU 5230 ZCC loves hacking 大数字的整数划分的更多相关文章
- HDU 4876 ZCC loves cards(暴力剪枝)
HDU 4876 ZCC loves cards 题目链接 题意:给定一些卡片,每一个卡片上有数字,如今选k个卡片,绕成一个环,每次能够再这个环上连续选1 - k张卡片,得到他们的异或和的数,给定一个 ...
- hdu 4873 ZCC Loves Intersection(大数+概率)
pid=4873" target="_blank" style="">题目链接:hdu 4873 ZCC Loves Intersection ...
- hdu 4876 ZCC loves cards(暴力)
题目链接:hdu 4876 ZCC loves cards 题目大意:给出n,k,l,表示有n张牌,每张牌有值.选取当中k张排列成圈,然后在该圈上进行游戏,每次选取m(1≤m≤k)张连续的牌,取牌上值 ...
- HDU 4873 ZCC Loves Intersection(可能性)
HDU 4873 ZCC Loves Intersection pid=4873" target="_blank" style="">题目链接 ...
- hdu 4882 ZCC Loves Codefires(数学题+贪心)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4882 ------------------------------------------------ ...
- hdu 5288 ZCC loves straight flush
传送门 ZCC loves straight flush Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K ...
- HDU 4882 ZCC Loves Codefires (贪心)
ZCC Loves Codefires 题目链接: http://acm.hust.edu.cn/vjudge/contest/121349#problem/B Description Though ...
- HDU 4882 ZCC Loves Codefires(贪心)
ZCC Loves Codefires Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/O ...
- HDU 5228 ZCC loves straight flush( BestCoder Round #41)
题目链接:pid=5228">ZCC loves straight flush pid=5228">题面: pid=5228"> ZCC loves s ...
随机推荐
- UITabBar 设置选中、未选中状态下title的字体颜色
一.如果只是设置选中状态的字体颜色,使用 tintColor 就可以达到效果 self.tabBar.tintColor = [UIColor redColor]; 二.但如果要将未选中状态和选中状 ...
- Git学习笔记 - Git安装
Git安装(Windows) 从 https://git-for-windows.github.io/ 下载Git,下载完成,双击安装,一路选择默认设置即可. 注意:选择使用git的命令行模式,选择默 ...
- im资源
https://github.com/oikomi/FishChatServer https://github.com/subrosa-io https://github.com/WhisperSys ...
- bzoj2257瓶子与燃料——最大公约数
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2257 可以知道最终能够导出的燃料一定是瓶子容量的gcd的倍数,所以此题转化为求n个数中k个数 ...
- sip协议呼叫流程详解
1.SIP业务基本知识 1.1 业务介绍会话初始协议(Session Initiation Protocol)是一种信令协议,用于初始.管理和终止网络中的语音和视频会话,具体地说就是用来生成.修改和终 ...
- Linux系统启动全过程
分为两部分,第一部分是硬件本身需要加载的信息,之后才是加载Linux相关信息,因为有装有双系统的机器嘛 1.计算机加电 2.BIOS开始运行,检测硬件:cpu.内存.硬盘等 3.BIOS读取CMOS存 ...
- 3-3Java程序的结构
这是类的定义 这是主方法的定义 类里面包含一个主方法,或者是主方法嵌套到我们的类里面 大括号要特别注意,通过大括号我们可以看到类和主方法的包含关系 class后面一定是跟的类的名字
- JSON 下 -- jansson 示例
JSON 下 —— jansson 示例 参考网址: jansson 库的下载: http://www.digip.org/jansson/ 安装jansson 步骤: http://blog.csd ...
- Memcached 查看帮助
进入到memcached目录, 输入命令: memcached -h 即可查看帮助 -p<num>要侦听的TCP端口号(默认值:11211) -u<num>udp监听端口号(默 ...
- 三星Gear VR与Oculus Rift DK2全方位比拼
网易数码1月6日消息,Oculus Rift DK2并不是面向消费者的产品,而三星Gear VR则进入了大众市场.虽然二者有点不同,但还是值得对比一番,看看Gear VR相比当下虚拟现实领域佼佼者Oc ...