NOIP2001提高组复赛B 数的划分
题目链接:https://ac.nowcoder.com/acm/contest/249/B
题目大意:
略
分析1(记忆化搜索):
方法为减而治之,把n划分成k份的答案就相当于每次把n分成a,b两个数,再把a分成k-1份,然后把每次a分成k-1份的答案相加即可。注意点是每轮分出来的b要不大于上一轮分出来的b。
代码如下:
#include <bits/stdc++.h>
using namespace std; #define rep(i,n) for (int i = 0; i < (n); ++i)
#define For(i,s,t) for (int i = (s); i <= (t); ++i)
#define rFor(i,t,s) for (int i = (t); i >= (s); --i)
#define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
#define rforeach(i,c) for (__typeof(c.rbegin()) i = c.rbegin(); i != c.rend(); ++i) #define pr(x) cout << #x << " = " << x << " "
#define prln(x) cout << #x << " = " << x << endl #define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin()) #define ms0(a) memset(a,0,sizeof(a))
#define msI(a) memset(a,inf,sizeof(a)) #define pii pair<int,int>
#define piii pair<pair<int,int>,int>
#define mp make_pair
#define pb push_back
#define fi first
#define se second inline int gc(){
static const int BUF = 1e7;
static char buf[BUF], *bg = buf + BUF, *ed = bg; if(bg == ed) fread(bg = buf, , BUF, stdin);
return *bg++;
} inline int ri(){
int x = , f = , c = gc();
for(; c<||c>; f = c=='-'?-:f, c=gc());
for(; c>&&c<; x = x* + c - , c=gc());
return x*f;
} typedef long long LL;
const int maxN = 1e5 + ; int n, k;
// f[i][j][k]表示数i分成j分的分法总数,k为限制条件,每种分法每份的值不能超过k,用来排除重复
// f[i][j][k] = f[i-1][j-1][1] + f[i-2][j-1][2] + ……+ f[i-min(k, i-1)][j-1][min(k, i-1)]
int f[][][]; int solve(int x, int y, int z){
int ret = ;
if(x < y) return ;
if(y == ) return x <= z ? : ;
if(f[x][y][z]) return f[x][y][z]; For(i, , x-) {
if(x-i > z) continue;
ret += solve(i, y-, x-i);
}
f[x][y][z] = ret;
return ret;
} int main(){
scanf("%d%d", &n, &k);
printf("%d\n", solve(n, k, ));
return ;
}
分析2(DP):
见代码内注释
代码如下:
#include <bits/stdc++.h>
using namespace std; #define rep(i,n) for (int i = 0; i < (n); ++i)
#define For(i,s,t) for (int i = (s); i <= (t); ++i)
#define rFor(i,t,s) for (int i = (t); i >= (s); --i)
#define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
#define rforeach(i,c) for (__typeof(c.rbegin()) i = c.rbegin(); i != c.rend(); ++i) #define pr(x) cout << #x << " = " << x << " "
#define prln(x) cout << #x << " = " << x << endl #define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin()) #define ms0(a) memset(a,0,sizeof(a))
#define msI(a) memset(a,inf,sizeof(a)) #define pii pair<int,int>
#define piii pair<pair<int,int>,int>
#define mp make_pair
#define pb push_back
#define fi first
#define se second inline int gc(){
static const int BUF = 1e7;
static char buf[BUF], *bg = buf + BUF, *ed = bg; if(bg == ed) fread(bg = buf, , BUF, stdin);
return *bg++;
} inline int ri(){
int x = , f = , c = gc();
for(; c<||c>; f = c=='-'?-:f, c=gc());
for(; c>&&c<; x = x* + c - , c=gc());
return x*f;
} typedef long long LL;
const int maxN = 1e5 + ; int n, k;
// f[i][j]表示数i分成j份的分法总数
/*
当i < j时,很明显没法分,所以f[i][j] = 0;
当i == j时,只有一种分法,所以f[i][j] = 1;
当i > j时,考虑从小到大分,第1个如果分1,那么f[i][j] = f[i-1][j-1];
第1个如果分大于1的数,可以对所有j份都减一,然后再分,即 f[i][j] = f[i-j][j];
根据加法原则,f[i][j] = f[i-1][j-1] + f[i-j][j];
*/
int f[][]; int main(){
scanf("%d%d", &n, &k);
For(i, , n) f[i][] = ; // 无论什么数,分成一份都只有一种
For(i, , k)
For(j, , n)
if(j >= i) f[j][i] = f[j-][i-] + f[j-i][i]; printf("%d\n", f[n][k]);
return ;
}
NOIP2001提高组复赛B 数的划分的更多相关文章
- 洛谷 P1025 & [NOIP2001提高组] 数的划分(搜索剪枝)
题目链接 https://www.luogu.org/problemnew/show/P1025 解题思路 一道简单的dfs题,但是需要剪枝,否则会TLE. 我们用dfs(a,u,num)来表示上一个 ...
- 【题解】NOIP2015提高组 复赛
[题解]NOIP2015提高组 复赛 传送门: 神奇的幻方 \([P2615]\) 信息传递 \([P2661]\) 斗地主 \([P2668]\) 跳石头 \([P2678]\) 子串 \([P26 ...
- 【题解】NOIP2016提高组 复赛
[题解]NOIP2016提高组 复赛 传送门: 玩具谜题 \(\text{[P1563]}\) 天天爱跑步 \(\text{[P1600]}\) 换教室 \(\text{[P1850]}\) 组合数问 ...
- NOIP 2015提高组复赛
神奇的幻方 题目描述 幻方是一种很神奇的N*N矩阵:它由数字1,2,3,……,N*N构成,且每行.每列及两条对角线上的数字之和都相同. 当N为奇数时,我们可以通过以下方法构建一个幻方: 首先将1写在第 ...
- noip2001提高组题解
今天继续感动滚粗.第一次提交170分,不能多说. 第一题:一元三次方程 明明是寒假讲分治的时候做过的题居然还是WA而且只拿了60分,说明知识掌握实在不够牢固. 寒假做的是保留4位小数,原题只保留2位, ...
- [日记&做题记录]-Noip2016提高组复赛 倒数十天
写这篇博客的时候有点激动 为了让自己不颓 还是写写日记 存存模板 Nov.8 2016 今天早上买了两个蛋挞 吃了一个 然后就做数论(前天晚上还是想放弃数论 但是昨天被数论虐了 woc noip模拟赛 ...
- 洛谷-神奇的幻方-NOIP2015提高组复赛
题目描述 幻方是一种很神奇的N*N矩阵:它由数字1,2,3,--,N*N构成,且每行.每列及两条对角线上的数字之和都相同. 当N为奇数时,我们可以通过以下方法构建一个幻方: 首先将1写在第一行的中间. ...
- 洛谷-乘积最大-NOIP2000提高组复赛
题目描述 Description 今年是国际数学联盟确定的“2000――世界数学年”,又恰逢我国著名数学家华罗庚先生诞辰90周年.在华罗庚先生的家乡江苏金坛,组织了一场别开生面的数学智力竞赛的活动,你 ...
- [NOIP2001提高组]CODEVS1014 Car的旅行路线(最短路)
最短路,这个不难想,但是要为它加边就有点麻烦..还好写完就过了(虽然WA了一次,因为我调试用的输出没删了..),不然实在是觉得挺难调的.. ------------------------------ ...
随机推荐
- 图解HTTP(1)之WEB及网络基础
HTTP协议访问Web 当你在浏览器地址栏中键入有效URL(统一资源定位符)相应的网页页面就会展示出来,那么它是如何展示出来的, 首先这存在两个概念 ------客户端.服务器端 客户端(client ...
- C# 如何创建Excel多级分组
在Excel中如果能够将具有多级明细的数据进行分组显示,可以清晰地展示数据表格的整体结构,使整个文档具有一定层次感.根据需要设置显示或者隐藏分类数据下的详细信息,在便于数据查看.管理的同时也使文档更具 ...
- 高效开发者是如何个性化VS Code插件与配置的?
2年之前,我放弃了Sublime Text,选择了Visual Studio Code作为代码编辑器. 我每天花在VS Code上的时间长达5~6个小时,因此按照我的需求优化VS Code配置十分必要 ...
- jsp基础语言-jsp动作
jsp动作是一组jsp内置的标签,用来控制jsp的行为,执行一些常用的jsp页面动作.通过jsp动作实现使用多行java代码能够实现的效果,即对常用的jsp功能进行抽象与封装. jsp共有七种标准的“ ...
- 前端入门11-JavaScript语法之数组
声明 本系列文章内容全部梳理自以下几个来源: <JavaScript权威指南> MDN web docs Github:smyhvae/web Github:goddyZhao/Trans ...
- 万能pb_ds头文件—bits/extc++.h
c++中自带了一些非常强大却鲜为人知的功能库—pd_ds库 里面含有红黑树(rb_tree),哈希表(gp_hash_table),可持久化平衡树(rope)等超强数据结构 但是有一件非常令人头痛的事 ...
- 解决注册并发问题并提高QPS
前言:前面在本地的windows通过apache的ab工具测试了600并发下“查询指定手机是否存在再提交数据”的注册功能会出现重复提交的情况,并且在注册完成时还需要对邀请人进行奖励,记录邀请记录,对该 ...
- Android为TV端助力 进制互相转换
byte转换为16进制 public static String GetByte2Str(byte b) { byte[] buff = new byte[2]; buff[0] = mHex[(b ...
- 2019Java查漏补缺(三)
1.为什么这个public的类的类名必须和文件名相同 是为了方便虚拟机在相应的路径中找到相应的类所对应的字节码文件 2.java8 的一些新特性: 3: 数据库隔离级别 隔离级别 ...
- Mysql学习路线
本文内容: mysql学习路线 首发日期:2018-04-19 由于现在很多都是有api了,很多问题都转接到编程语言上来处理了,所以这篇mysql之路仅仅是作为“了解”之用.不深究mysql. 很多东 ...