梳理一下最近准备蓝桥杯时学习DP问题的想法
学习时间不长,记录的只是学习过程的思路和想法,不能保证正确,代码可以在acwing上AC。
01背包问题:
1.首先是简单的01背包问题
2.先确定状态,f[i][j]表示有第i件物品,时间为j的最大价值。
3.第i件物品取时f[i][j]=f[i-1][j-W[i]]+V[i],第i件物品不取时f[i][j]=f[i-1][j],物品只有取与不取两种情况,所以两个值取一个最大值即可
4.保证不重不漏的考虑了所有情况,f[n][m]就是答案。
4.放一个二维的简单写法,以及一维的优化写法。
#include<stdio.h>
#define X 1010
int f[X][X];
int V[X],W[X];
int max(int a,int b)
{
return a>b?a:b;
} int main(void)
{
int n,v;
scanf("%d%d",&n,&v);
for(int i = 1; i <= n ; i++)scanf("%d%d",&V[i],&W[i]);
for(int i = 1; i <= n ; i++)
for(int j = v ; j >=0 ; j--){
f[i][j]=f[i-1][j];
if(j>=V[i])f[i][j]=max(f[i][j],f[i-1][j-V[i]]+W[i]);
}
printf("%d",f[n][v]);
return 0 ;
}
#include<stdio.h>
#define X 1010
int f[X];
int res;
int max(int a,int b)
{
return a>b?a:b;
}
int main(void)
{
int n,m,v,w;
scanf("%d %d",&n,&m);
for(int i = 1 ; i <= n ; i++){
scanf("%d %d",&v,&w);
for(int j = m ; j >= v ; j--){
//从大到小逆序更新f[j],防止利用第i轮的较小数据更新第i轮的较大数据
//保证每一轮较大f[j]更新时使用的是第i-1轮的较小f[j]
f[j]=max(f[j],f[j-v]+w);
if(res<f[j])res=f[j];
}
} printf("%d",f[m]); return 0;
}
摘花生:
1.还是一道很基础的DP问题
2.依旧先确定状态,f[i][j]表示第i行第j列时花生的数量。
3.只能向下走或者向右走两种情况,所以取向下走到f[i][j]和向右走到f[i][j]的最大值加上f[i][j]处的花生。
f[i][j]=max(f[i-1][j],f[i][j-1])+f[i][j]。
4.不断更新到f[r][c]就是答案。
5.水平有限只会写简单写法,可以去acwing上看大佬写的滚动数组优化和一维的优化写法。有机会学习完回来更新下优化写法。
#include<stdio.h>
#define X 110
int a[X][X];
int max (int a, int b )
{
return a > b ? a : b;
}
int main(void)
{
int n;
scanf("%d",&n);
while(n--)
{
int c,r;
scanf("%d %d",&r,&c);
for(int i = 1 ; i <= r ; i++){
for(int j = 1 ; j <= c ; j++){
scanf("%d",&a[i][j]);
a[i][j]+=max(a[i-1][j],a[i][j-1]);
}
}
printf("%d\n",a[r][c]);
}
return 0;
}
最长上升子序列:
1.不难的一道基础题。
2.先确定状态,f[i]表示以a[i]结尾的最长子序列长度。只要a[j]<a[i],那么f[i]就应该等于f[j]+1,与f[i]两者的最大值;
3.更新每一个f[i]的值,最大值就是最长子序列长度。
4.可以去acwing上看大佬写的动规加二分做法,时间复杂度可以达到O(nlogn)。
#include<stdio.h>
#define X 1010
int a[X],f[X],res;
int max(int a,int b)
{
return a>b?a:b;
}
int main(void)
{
int n;
scanf("%d",&n);
for(int i = 0 ; i < n ; i++){
scanf("%d",&a[i]);
}
for(int i = 0; i < n ;i ++){
f[i]=1;
for(int j = 0; j < i ; j++){
if(a[i]>a[j])f[i]=max(f[i],f[j]+1);
if(f[i]>res)res=f[i];
}
}
printf("%d",res); return 0;
}
波动数列:
1.蓝桥杯原题,对现在的我来说有点难,看完讲解一步步做的。
2.还是先确定状态,方程f[i][j]表示以加到第i项的和模n余数为j的个数。
3.关键点在于推出s和n-1项的数列和模n同余。
4.f[i][j]=(f[i-1][(j-i*a)%n]+f[i-1][(j+i*b)%n])%MOD。
5.类似背包的问题的组合,但是有点抽象,将每种可能需要状态推出,下一层利用上一层存下的状态接着推出结果。
6.利用3中的结论答案就是f[n-1][s%n]。
7。注意每次取余需要用(a%b+b)%b这个公式转换为正余数。
#include<stdio.h>
#define MOD 100000007
#define X 1010
int get_mod(int a,int b)
{
return (a%b+b)%b;
}
int f[X][X];
int main(void)
{
int n,s,a,b;
scanf("%d%d%d%d",&n,&s,&a,&b);
f[0][0]=1;
for(int i = 1 ; i < n ; i++)
for(int j = 0 ; j < n ; j++)
f[i][j]=(f[i-1][get_mod(j-i*a,n)]+f[i-1][get_mod(j+i*b,n)])%MOD;
printf("%d",f[n-1][get_mod(s,n)]);
return 0;
}
地宫取宝:
1.蓝桥杯原题,水平有限,还是看完讲解后一步步做的。
2.对于DP问题的如何初始化正确的初始化,还是有点疑惑,还是题目写的少了。
3.还是确定状态f[i][j][u][v]表示位于i,j,手中的物品有u件,手中物品的最大价值为v。
4.有点类似背包问题,同样需要分成拿与不拿的两种情况。
5.不拿的情况等于向右走到i,j和向左走到i,j两种情况的方案和,拿的情况应该是上一轮所以可能可以取的情况的方案和,需要遍历求和。
6.最后答案就是在i,j位置取了k件的所有方案和,因为数字很大可能会爆int,所有每进行一次两个数相加就要取模一次。
7.最开始取零件最大价值为0只有一种合法方案,取一件的合法方案也只有一种,所以将两种情况初始化为1。
#include<stdio.h>
#define X 51
#define MOD 1000000007
#define K 13
#define C 14
int f[X][X][K][C];//在i,j处时有u件物品,此时的最大价值是v
int W[X][X];
int main(void)
{
int n,m,k;
scanf("%d %d %d",&n,&m,&k);
for(int i = 1 ; i <= n ; i ++)
for(int j = 1 ; j <= m ; j ++)
scanf("%d",&W[i][j]),W[i][j]++;
//最开始取了
f[1][1][1][W[1][1]]=1;
//最开始不取
f[1][1][0][0]=1;
for(int i = 1 ; i <= n ; i ++ ){
for(int j = 1 ; j <= m ; j++){
for(int u = 0 ; u <= 12 ; u++){
for(int v = 0 ; v <= 13 ; v++){
int &val = f[i][j][u][v];
//不拿
val = (val + f[i-1][j][u][v]) % MOD;
val = (val + f[i][j-1][u][v]) % MOD;
//拿
if(u>0&&v==W[i][j]){
//加上上一轮的所有可能可以拿的情况
for(int c = 0 ; c < v ; c++){
val=(val+f[i-1][j][u-1][c])%MOD;
val=(val+f[i][j-1][u-1][c])%MOD;
}
}
}
}
}
}
int res=0;
for(int i = 0 ; i <= 13 ;i++)res=(res+f[n][m][k][i])%MOD;
printf("%d",res); return 0;
}
梳理一下最近准备蓝桥杯时学习DP问题的想法的更多相关文章
- java实现第四届蓝桥杯好好学习
好好学习 汤姆跟爷爷来中国旅游.一天,他帮助中国的小朋友贴标语.他负责贴的标语是分别写在四块红纸上的四个大字:"好.好.学.习".但是汤姆不认识汉字,他就想胡乱地贴成一行. 请你替 ...
- 蓝桥杯 求最大值 dp
这题很暴力的一个DP,d[i][j]表示前i个数对选择一些Ai的和为j的最大Bi和. 状态转移方程: dp[i][j]=max(dp[i][j],dp[i-1][j-sc[i].a]+sc[i].b) ...
- 计蒜客 蓝桥杯模拟 瞬间移动 dp
在一个 n \times mn×m 中的方格中,每个格子上都有一个分数,现在蒜头君从 (1,1)(1,1) 的格子开始往 (n, m)(n,m) 的格子走.要求从 (x_1,y_1)(x1,y1 ...
- 2013第四届蓝桥杯决赛Java高职高专组题目以及解法答案
2013第四届蓝桥杯决赛Java高职高专组题目以及解法答案 不知不觉离决赛都过去一个月了,一直忙于各种事情,都忘记整理一份试题.当作回忆也好. 1. 标题:好好学习 汤姆跟爷爷来中国旅游.一天,他帮助 ...
- 蓝桥杯第九届省赛 sscanf(),str.c_str()函数的使用
标题:航班时间 [问题背景]小h前往美国参加了蓝桥杯国际赛.小h的女朋友发现小h上午十点出发,上午十二点到达美国,于是感叹到“现在飞机飞得真快,两小时就能到美国了”. 小h对超音速飞行感到十分恐惧.仔 ...
- 树形dp|无根树转有根树|2015年蓝桥杯生命之树
2015年蓝桥杯第十题--生命之树(无根树dfs) ①暴力解法:枚举子集(选点) + dfs判断连通性(题目要求连通)满足上面两个条件下找出最大值权值和 ②dfs无根树转有根树,递归找最优 先学习无根 ...
- 【蓝桥杯单片机11】单总线温度传感器DS18B20的基本操作
[蓝桥杯单片机11]单总线温度传感器DS18B20的基本操作 广东职业技术学院 欧浩源 单总线数字温度传感器DS18B20几乎成了各类单片机甚至ARM实验板的标配模块来,在蓝桥杯的往届省赛和国赛中,这 ...
- java算法 蓝桥杯 文化之旅
问题描述 有一位使者要游历各国,他每到一个国家,都能学到一种文化,但他不愿意学习任何一种文化超过一次(即如果他学习了某种文化,则他就不能到达其他有这种文化的国家).不同的国家可能有相同的文化.不同文化 ...
- C语言蓝桥杯比赛原题和解析
蓝桥杯:在计算机编程领域,是具有一定含金量的竞赛,用于选拔信息技术人才. 一般分为多个领域,其中包含了C/C#/C++/Java/Python等编程语言的测试题,多为算法的设计题. 下面,在搜题过程中 ...
随机推荐
- Linux & bash & tcpdump
Linux & bash & tcpdump Linux & tcpdump https://www.tecmint.com/12-tcpdump-commands-a-net ...
- how to get window width in javascript
how to get window width in javascript how to get window width in js How to Detect Screen Resolution ...
- Flutter 使用Tabbar不要Title
原文 Demo 1 import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp ext ...
- 01.Numpy数组的基本应用
数组的创建 数组的访问 数组的合并 数组的分割 数组创建 >>> import numpy as np 创建一维数组 >>> x = np.arange(10) & ...
- 小公举comm,快速比较两个排序文件
前言 我们经常会有需求比较一个文件里的内容是否在另一个文件存在.假如我有一份监控列表的IP写入在了file1,我所有的机器IP写入在了file2,我要找出还有哪些机器没有在监控列表.以前的做法是写个两 ...
- Git:使用远程仓库
远程仓库可使用Github.Gitee,或自建Gitlab.Gogs服务器,这里使用Github. 配置本地用户名和邮箱 # 配置本地用户的用户名邮箱(保存在用户.gitconfig文件) $ git ...
- 一文了解python的 @property
参考自: https://www.programiz.com/python-programming/property Python为我们提供了一个内置装饰器@property,此方法使得getter和 ...
- Win10下ctrl与alt键互换
我之前尝试过用第三方软件修改,但是总是不成功,后来发现直接去修改注册表也不麻烦,记录一下步骤. win + r 输入 regedit 进到这个路径 点击Keyboard Layout 右键,新建一个 ...
- pytorch(14)权值初始化
权值的方差过大导致梯度爆炸的原因 方差一致性原则分析Xavier方法与Kaiming初始化方法 饱和激活函数tanh,非饱和激活函数relu pytorch提供的十种初始化方法 梯度消失与爆炸 \[H ...
- C#深度复制和浅度复制
C#深度复制和浅度复制 复制一个值变量很简单,新建一个变量然后将原来的变量赋值过去就行,但是复制一个引用变量这种方法是不行的,如果不明白为什么可以先看看这篇解释 引用类型变量和值类型变量在赋值时的不同 ...