学习时间不长,记录的只是学习过程的思路和想法,不能保证正确,代码可以在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. Linux & bash & tcpdump

    Linux & bash & tcpdump Linux & tcpdump https://www.tecmint.com/12-tcpdump-commands-a-net ...

  2. 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 ...

  3. Flutter 使用Tabbar不要Title

    原文 Demo 1 import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp ext ...

  4. 01.Numpy数组的基本应用

    数组的创建 数组的访问 数组的合并 数组的分割 数组创建 >>> import numpy as np 创建一维数组 >>> x = np.arange(10) & ...

  5. 小公举comm,快速比较两个排序文件

    前言 我们经常会有需求比较一个文件里的内容是否在另一个文件存在.假如我有一份监控列表的IP写入在了file1,我所有的机器IP写入在了file2,我要找出还有哪些机器没有在监控列表.以前的做法是写个两 ...

  6. Git:使用远程仓库

    远程仓库可使用Github.Gitee,或自建Gitlab.Gogs服务器,这里使用Github. 配置本地用户名和邮箱 # 配置本地用户的用户名邮箱(保存在用户.gitconfig文件) $ git ...

  7. 一文了解python的 @property

    参考自: https://www.programiz.com/python-programming/property Python为我们提供了一个内置装饰器@property,此方法使得getter和 ...

  8. Win10下ctrl与alt键互换

    我之前尝试过用第三方软件修改,但是总是不成功,后来发现直接去修改注册表也不麻烦,记录一下步骤. win + r 输入 regedit 进到这个路径 点击Keyboard Layout 右键,新建一个 ...

  9. pytorch(14)权值初始化

    权值的方差过大导致梯度爆炸的原因 方差一致性原则分析Xavier方法与Kaiming初始化方法 饱和激活函数tanh,非饱和激活函数relu pytorch提供的十种初始化方法 梯度消失与爆炸 \[H ...

  10. C#深度复制和浅度复制

    C#深度复制和浅度复制 复制一个值变量很简单,新建一个变量然后将原来的变量赋值过去就行,但是复制一个引用变量这种方法是不行的,如果不明白为什么可以先看看这篇解释 引用类型变量和值类型变量在赋值时的不同 ...