学习时间不长,记录的只是学习过程的思路和想法,不能保证正确,代码可以在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问题的想法的更多相关文章

  1. java实现第四届蓝桥杯好好学习

    好好学习 汤姆跟爷爷来中国旅游.一天,他帮助中国的小朋友贴标语.他负责贴的标语是分别写在四块红纸上的四个大字:"好.好.学.习".但是汤姆不认识汉字,他就想胡乱地贴成一行. 请你替 ...

  2. 蓝桥杯 求最大值 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) ...

  3. 计蒜客 蓝桥杯模拟 瞬间移动 dp

      在一个 n \times mn×m 中的方格中,每个格子上都有一个分数,现在蒜头君从 (1,1)(1,1) 的格子开始往 (n, m)(n,m) 的格子走.要求从 (x_1,y_1)(x1​,y1 ...

  4. 2013第四届蓝桥杯决赛Java高职高专组题目以及解法答案

    2013第四届蓝桥杯决赛Java高职高专组题目以及解法答案 不知不觉离决赛都过去一个月了,一直忙于各种事情,都忘记整理一份试题.当作回忆也好. 1. 标题:好好学习 汤姆跟爷爷来中国旅游.一天,他帮助 ...

  5. 蓝桥杯第九届省赛 sscanf(),str.c_str()函数的使用

    标题:航班时间 [问题背景]小h前往美国参加了蓝桥杯国际赛.小h的女朋友发现小h上午十点出发,上午十二点到达美国,于是感叹到“现在飞机飞得真快,两小时就能到美国了”. 小h对超音速飞行感到十分恐惧.仔 ...

  6. 树形dp|无根树转有根树|2015年蓝桥杯生命之树

    2015年蓝桥杯第十题--生命之树(无根树dfs) ①暴力解法:枚举子集(选点) + dfs判断连通性(题目要求连通)满足上面两个条件下找出最大值权值和 ②dfs无根树转有根树,递归找最优 先学习无根 ...

  7. 【蓝桥杯单片机11】单总线温度传感器DS18B20的基本操作

    [蓝桥杯单片机11]单总线温度传感器DS18B20的基本操作 广东职业技术学院 欧浩源 单总线数字温度传感器DS18B20几乎成了各类单片机甚至ARM实验板的标配模块来,在蓝桥杯的往届省赛和国赛中,这 ...

  8. java算法 蓝桥杯 文化之旅

    问题描述 有一位使者要游历各国,他每到一个国家,都能学到一种文化,但他不愿意学习任何一种文化超过一次(即如果他学习了某种文化,则他就不能到达其他有这种文化的国家).不同的国家可能有相同的文化.不同文化 ...

  9. C语言蓝桥杯比赛原题和解析

    蓝桥杯:在计算机编程领域,是具有一定含金量的竞赛,用于选拔信息技术人才. 一般分为多个领域,其中包含了C/C#/C++/Java/Python等编程语言的测试题,多为算法的设计题. 下面,在搜题过程中 ...

随机推荐

  1. stackoverflow & xgqfrms

    stackoverflow & xgqfrms stackoverflow https://stackoverflow.com/users/5934465/xgqfrms https://st ...

  2. vscode & peacock extension

    vscode & peacock extension https://marketplace.visualstudio.com/items?itemName=johnpapa.vscode-p ...

  3. Hystrix熔断器的使用步骤

    1.添加熔断器依赖 2.在配置文件中开启熔断器 feign.hystrix.enabled=true 3.写接口的实现类VodFileDegradeFeignClient,在实现类中写如果出错了输出的 ...

  4. 【死磕JVM】JVM快速入门之前戏篇

    简介 Java是一门可以跨平台的语言,但是Java本身是不可以实现跨平台的,需要JVM实现跨平台.javac编译好后的class文件,在Windows.Linux.Mac等系统上,只要该系统安装对应的 ...

  5. 学习String源码的部分方法

    先看构造器: private final char value[]; //char类型的数组 以下均会用到 private int hash; //缓存字符串的哈希值 //以下均会用到 public ...

  6. 前端传递数据到后台的两种方式;创建一个map或者创建一个FormData对象

    一.构建一个map getAllDeptAllUsers(){ const modleCode = {'auditMenuId': this.auditMenuId, 'enterpriseId': ...

  7. 死磕Spring之IoC篇 - 解析自定义标签(XML 文件)

    该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读 Spring 版本:5.1. ...

  8. Svelte 码半功倍

    你未注意到的最重要的指标. 注意:原文发表于2019-04-20,随着框架不断演进,部分内容可能已不适用. 所有代码都有 BUG,你写的越多,BUG 越多,这很合情合理. 同时,写的越多,费时越多,留 ...

  9. 后端程序员之路 14、NumPy

    NumPy - NumPyhttp://www.numpy.org/ NumPy-快速处理数据 - 用Python做科学计算http://old.sebug.net/paper/books/scipy ...

  10. Python3.x 基础练习题100例(81-90)

    练习81: 题目: 809??=800??+9?? 其中??代表的两位数, 809??为四位数,8??的结果为两位数,9??的结果为3位数.求??代表的两位数,及809*??后的结果. 程序: a = ...