蓝桥杯 --- 数学与简单DP

这篇具有很好参考价值的文章主要介绍了蓝桥杯 --- 数学与简单DP。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

数学

1205. 买不到的数目

小明开了一家糖果店。

他别出心裁:把水果糖包成4颗一包和7颗一包的两种。

糖果不能拆包卖。

小朋友来买糖的时候,他就用这两种包装来组合。

当然有些糖果数目是无法组合出来的,比如要买 10 颗糖。

你可以用计算机测试一下,在这种包装情况下,最大不能买到的数量是17。

大于17的任何数字都可以用4和7组合出来。

本题的要求就是在已知两个包装的数量时,求最大不能组合出的数字。

输入格式
两个正整数 n,m,表示每种包装中糖的颗数。

输出格式
一个正整数,表示最大不能买到的糖数。

数据范围

2≤n,m≤1000, 保证数据一定有解。

输入样例:

4 7

输出样例:

17

解题思路
裴蜀定理

#include<iostream>

using namespace std;

int main() {
	
	int n, m;
	cin >> n >> m;
	cout << (n - 1) * (m - 1) - 1 << endl;
	
} 

1211. 蚂蚁感冒

长 100 厘米的细长直杆子上有 n 只蚂蚁。

它们的头有的朝左,有的朝右。

每只蚂蚁都只能沿着杆子向前爬,速度是 1 厘米/秒。

当两只蚂蚁碰面时,它们会同时掉头往相反的方向爬行。

这些蚂蚁中,有 1 只蚂蚁感冒了。

并且在和其它蚂蚁碰面时,会把感冒传染给碰到的蚂蚁。

请你计算,当所有蚂蚁都爬离杆子时,有多少只蚂蚁患上了感冒。

输入格式
第一行输入一个整数 n, 表示蚂蚁的总数。

接着的一行是 n 个用空格分开的整数 Xi, Xi 的绝对值表示蚂蚁离开杆子左边端点的距离。

正值表示头朝右,负值表示头朝左,数据中不会出现 0 值,也不会出现两只蚂蚁占用同一位置。

其中,第一个数据代表的蚂蚁感冒了。

输出格式
输出1个整数,表示最后感冒蚂蚁的数目。

数据范围

1<n<50 , 0<|Xi|<100

输入样例1:

3
5 -2 8

输出样例1:

1

输入样例2:

5
-10 8 -20 12 25

输出样例2:

3

解题思路
首先我们必须要明白两只蚂蚁相撞掉头可以看作时一只蚂蚁穿过了另一只蚂蚁,因为相撞之后两只蚂蚁都感冒了,掉不掉头其实无所谓,毕竟都感冒了,这样的话这题就简单多了。我们先不考虑特殊情况,先来看看一般情况:

第一只蚂蚁不管方向朝哪里,只要它右边的蚂蚁向左走就可能碰撞感染,同样,第一只蚂蚁左边的蚂蚁只要朝右边走也可能被感染,这样就很容易得到ans=right+left+1。这里left表示左边蚂蚁向右走的数量,right表示右边蚂蚁向左走的数量,1是指第一只蚂蚁本身。

还有一种特殊情况,就是当第一只蚂蚁向左走的时候,如果第一只蚂蚁左边没有向右爬行的蚂蚁,由于爬行速度相同,所以不管第一只蚂蚁右边有多少向左爬行的,其右边的蚂蚁永远不可能被感染。同理,当第一只蚂蚁向右走的时候,如果第一只蚂蚁右边没有向左爬行的蚂蚁,其左边也永远不可能感染。

#include<iostream>
#include<algorithm>

using namespace std;

int n;
int f[55];

int main() {
	
	cin >> n;
	int l = 0, r = 0;
	for(int i = 0; i <= n; i ++ ) cin >> f[i];
	for(int i = 0; i <= n; i ++ ) {
		if(abs(f[i]) < abs(f[0]) && f[i] > 0) l ++ ;
		if(abs(f[i]) > abs(f[0]) && f[i] < 0) r ++ ;
	}
	if(f[0] > 0) {
		if(r > 0) cout << l + r + 1 << endl;
		else cout << 1 << endl;
	}
	else {
		if(l > 0) cout << l + r + 1 << endl;
		else cout << 1 << endl;
	}
	
	return 0;
	
}

1216. 饮料换购

乐羊羊饮料厂正在举办一次促销优惠活动。乐羊羊C型饮料,凭3个瓶盖可以再换一瓶C型饮料,并且可以一直循环下去(但不允许暂借或赊账)。

请你计算一下,如果小明不浪费瓶盖,尽量地参加活动,那么,对于他初始买入的 n 瓶饮料,最后他一共能喝到多少瓶饮料。

输入格式
输入一个整数 n,表示初始买入的饮料数量。

输出格式
输出一个整数,表示一共能够喝到的饮料数量。

数据范围

0<n<10000

输入样例:

100

输出样例:

149

解题思路
纯模拟…

#include<iostream>

using namespace std;

int n;

int main() {
	
	cin >> n;
	
	int pre = n / 3 + n % 3;
	int ans = n / 3;
	while(pre >= 3) {
		ans += pre / 3;
		pre = pre / 3 + pre % 3;
	}
	
	cout << n + ans << endl;
	
	return 0;
	
}

简单DP

2. 01背包问题

有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。

第 i 件物品的体积是 vi,价值是 wi。

求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
输出最大价值。

输入格式
第一行两个整数,N,V,用空格隔开,分别表示物品数量和背包容积。

接下来有 N 行,每行两个整数 vi,wi,用空格隔开,分别表示第 i 件物品的体积和价值。

输出格式
输出一个整数,表示最大价值。

数据范围

0<N,V≤1000

0<vi,wi≤1000

输入样例

4 5
1 2
2 4
3 4
4 5

输出样例:

8

解题思路

//f[i][j]表示只选前i个物品(并不是前i个都选),总体积是j,总价值最大是多少(注意是最大,每次迭代的时候都是取的最大值) 
//对于第i件物品有两种选择:1.选第i件物品,2.不选第i件物品
//选第i件:f[i][j] = f[i - 1][j - v[i]]
//不选第i件:f[i][j] = f[i - 1][j]
//最后f[i][j] = max(1, 2) 
//result=max(f[n][0-j]) 


#include<iostream>

using namespace std;

const int N = 1010;

int n, m;
int v[N], w[N];
int f[N][N];

int main() {
	
	cin >> n >> m;
	for(int i = 1; i <= n; i ++ ) cin >> v[i] >> w[i];
	for(int i = 1; i <= n; i ++ ) {
		for(int j = 0; j <= m; j ++ ) {
			f[i][j] = f[i - 1][j];
			if(j >= v[i]) f[i][j] = max(f[i - 1][j], f[i - 1][j - v[i]] + w[i]);
		}
	}
	
	int ans = 0;
	for(int i = 0; i <= m; i ++ ) {
		ans = max(ans, f[n][i]);
	}
	cout << ans << endl;
	
	return 0;
}

优化成一维

#include<iostream>

using namespace std;

const int N = 1010;

int n, m;
int v[N], w[N];
int f[N];

int main() {
	
	cin >> n >> m;
	for(int i = 1; i <= n; i ++ ) cin >> v[i] >> w[i];
	for(int i = 1; i <= n; i ++ ) {
		for(int j = m; j >= v[i]; j -- ) {
			f[j] = max(f[j], f[j - v[i]] + w[i]);
		}
	}
	
	int ans = 0;
	for(int i = 0; i <= m; i ++ ) {
		ans = max(ans, f[i]);
	}
	cout << ans << endl;
	
	return 0;
}

1015. 摘花生

Hello Kitty想摘点花生送给她喜欢的米老鼠。

她来到一片有网格状道路的矩形花生地(如下图),从西北角进去,东南角出来。

地里每个道路的交叉点上都有种着一株花生苗,上面有若干颗花生,经过一株花生苗就能摘走该它上面所有的花生。

Hello Kitty只能向东或向南走,不能向西或向北走。

问Hello Kitty最多能够摘到多少颗花生。

蓝桥杯 --- 数学与简单DP

输入格式
第一行是一个整数T,代表一共有多少组数据。

接下来是T组数据。

每组数据的第一行是两个整数,分别代表花生苗的行数R和列数 C。

每组数据的接下来R行数据,从北向南依次描述每行花生苗的情况。每行数据有C个整数,按从西向东的顺序描述了该行每株花生苗上的花生数目M。

输出格式
对每组输入数据,输出一行,内容为Hello Kitty能摘到得最多的花生颗数。

数据范围

1≤T≤100,
1≤R,C≤100,
0≤M≤1000

输入样例:

2
2 2
1 1
3 4
2 3
2 3 4
1 6 5

输出样例:

8
16

解题代码

  1. 状态表示
    集合:定义 f[i][j] 为从 ( 1 , 1 ) 到 ( i , j ) 的所有方案的集合
    属性:最大值
  2. 状态转移
    ( i , j ) 从 ( i - 1 , j ) 转移过来
    ( i , j ) 从 ( i , j - 1 ) 转移过来
  3. 空间压缩
    f[i][j] 主需要用到这一层和上一层的 f 元素,所以可以压缩成滚动数组。再次之上,还可以直接压缩成一维数组。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<stack>
#include<queue>
#include<sstream>
#include<set>
#include<map>

#define x first
#define y second

using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 110;
const int MOD = 1000000007;
const int INF = 0x3f3f3f3f;

int gcd(int a, int b){return b ? gcd(b, a % b) : a;}

int g[N][N];
int f[N][N];

int main()
{
	int t;
	cin >> t;
	while(t -- ) {
		int r, c;
		cin >> r >> c;
		for(int i = 1; i <= r; i ++ ) {
			for(int j = 1; j <= c; j ++ ) {
				cin >> g[i][j];
			}
		}
		for(int i = 1; i <= r; i ++ ) {
			for(int j = 1; j <= c; j ++ ) {
				f[i][j] = max(f[i - 1][j] + g[i][j], f[i][j - 1] + g[i][j]);
			}
		}
		int ans = 0;
		for(int i = 1; i <= r; i ++ ) {
			for(int j = 1; j <= c; j ++ ) {
				ans = max(ans, f[i][j])
			}
		}
		cout << ans << endl;
	}

	return 0;
}

895. 最长上升子序列

给定一个长度为 N 的数列,求数值严格单调递增的子序列的长度最长是多少。

输入格式
第一行包含整数 N。

第二行包含 N 个整数,表示完整序列。

输出格式
输出一个整数,表示最大长度。

数据范围

1≤N≤1000,
−109≤数列中的数≤109

输入样例:

7
3 1 2 1 8 5 6

输出样例:

4

解题思路文章来源地址https://www.toymoban.com/news/detail-405287.html

  1. 状态表示
    f[i] 表示从第一个数字开始,以 a[i] 结尾的最大上升的序列
  2. 状态计算
    f[i] = max( f[i] , f[j] + 1 )
    有一个边界,若前面没有比 a[i] 小的,f[i] 为 1(自己开头,自己结尾)
  3. 结果
    f[i] 中找出最大值
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<stack>
#include<queue>
#include<sstream>
#include<set>
#include<map>

#define x first
#define y second

using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 1010;
const int MOD = 1000000007;
const int INF = 0x3f3f3f3f;

int gcd(int a, int b){return b ? gcd(b, a % b) : a;}

int a[N];
int f[N];

int main()
{
	int n;
	cin >> n;
	for(int i = 1; i <= n; i ++ ) cin >> a[i];
	int ans = 0;
	for(int i = 1; i <= n; i ++ ) {
		f[i] = 1;
		for(int j = 1; j < i; j ++ ) {
			if(a[i] > a[j]) {
				f[i] = max(f[i], f[j] + 1);
			}
		}
	}
	for(int i = 1; i <= n; i ++ ) {
	    ans = max(ans, f[i]);
	}
	cout << ans << endl;

	return 0;
}



到了这里,关于蓝桥杯 --- 数学与简单DP的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 买不到的数目(最大不能组合的数)

    提示信息:   因数:因数是指整数a除以整数b(b≠0)的商正好是整数而没有余数,我们就说b是a的因数。 公因数:给定若干个整数,如果有一个(些)数是它们共同的因数,那么这个(些)数就叫做它们的公因数。 互质数:公因数只有1的两个非零自然数,叫做互质数;例如2和3,公

    2023年04月09日
    浏览(60)
  • [Python]补充程序实现以下计算小明参加语文,数学和英语考试,输入小明的3门课程考试成绩,计算并输出3门课程考试成绩的和、平均值以及最高和最低分。 如果三门课程以权重0.5,0.3和0.2计入总分

    补充程序实现以下计算 小明参加语文,数学和英语考试,输入小明的3门课程考试成绩,计算并输出3门课程考试成绩的和、平均值以及最高和最低分。 如果三门课程以权重0.5,0.3和0.2计入总分,计算并输出小明的最终总评成绩。 输入样例: 输出样例:

    2024年03月14日
    浏览(87)
  • 【蓝桥杯】DP和枚举(持续更新~~~)

    😽 PREFACE 🎁欢迎各位→点赞 👍 + 收藏 ⭐ + 评论 📝 📢系列专栏: 蓝桥杯 🔊本专栏涉及到的知识点或者题目是算法专栏的补充与应用 💪 种一棵树最好是十年前其次是现在 DP就是动态规划,其类型有以下两个特征: 重叠子问题:子问题是原大问题的小版本,计算步骤完全

    2023年04月08日
    浏览(31)
  • 蓝桥杯真题:密码脱落(区间dp)

    目录 题目: 解题思路: dp分析:  解题代码: 题目要求的为脱落的种子数(即回文字符中没有对应回文的字符的数量) 我们可以转换成求回文字符串最长回文字符串的长度

    2024年02月16日
    浏览(27)
  • 动态规划树形DP课后习题蓝桥舞会

      蓝桥舞会 题目描述 蓝桥公司一共有n名员工,编号分别为1~n。 他们之间的关系就像一棵以董事长为根的树,父节点就是子节点的直接上司。每个员工有一个快乐指数aj。 现蓝桥董事会决定举办一场蓝桥舞会来让员工们在工作之余享受美好时光,不过对于每个员工,他们都

    2024年02月21日
    浏览(33)
  • Leetcode—2678.老人的数目【简单】

    之后我会持续更新,如果喜欢我的文章,请记得一键三连哦,点赞关注收藏,你的每一个赞每一份关注每一次收藏都将是我前进路上的无限动力 !!!↖(▔▽▔)↗感谢支持!

    2024年02月08日
    浏览(24)
  • 第十四届蓝桥杯. 接龙数列(线性DP)

    对于一个长度为 K 的整数数列:A1,A2,...,AK,我们称之为接龙数列当且仅当 A i 的首位数字恰好等于 A i−1 的末位数字 (2≤i≤K)。 例如 12,23,35,56,61,11 是接龙数列;12,23,34,56 不是接龙数列,因为 56 的首位数字不等于 34 的末位数字。 所有长度为 11 的整数数列都是接龙数

    2024年02月02日
    浏览(25)
  • 蓝桥杯备赛之动态规划篇——涂色问题(区间DP)

    2023第十四届蓝桥杯模拟赛第二期个人题解(Java实现) 2023第十四届蓝桥杯模拟赛第三期个人题解(Java实现) 蓝桥杯备赛之动态规划篇——背包问题 蓝桥杯真题——单词分析(Java实现) 😘😘 哈喽,大家好!这里是蓝桥杯系列文章的动态规划章节🔥🔥,今天要讲解的是区

    2024年01月23日
    浏览(34)
  • MySql报1205:1205 - Lock wait timeout exceeded; try restarting transaction,出现1205如何解决

    问题:当在mysql执行一个DDL语句时候,报1205. 本来想删除一段时间的数据,语句如下: 报错如下:1205 - Lock wait timeout exceeded; try restarting transaction,主要是源数据都是屁了insert的,可能没有提交,资源被占,现在杀掉这个 锁住的进程id就OK。 1.执行 SHOW FULL PROCESSLIST,找到这个

    2024年02月13日
    浏览(43)
  • Codeforces 1855E 数学期望 + DP

    题意 传送门 Codeforces 1855E Expected Destruction 题解 将 S i S_i S i ​ 运动至 S i + 1 S_{i+1} S i + 1 ​ 的情况看作后者消失,则 S i S_i S i ​ 在碰到 S i + 1 S_{i + 1} S i + 1 ​ 前, S i + 1 S_{i + 1} S i + 1 ​ 必然存在。 根据数学期望的线性性质,可以独立地考虑每一个 S i S_i S i ​ 在碰到 S i

    2024年02月06日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包