动态规划

  • A : "1+1+1+1+1+1+1+1 =?"
  • A : "上面等式的值是多少"
  • B : 计算 "8"
  • A : 在上面等式的左边写上 "1+" 呢?
  • A : "此时等式的值为多少"
  • B : 很快得出答案 "9"
  • A : "你怎么这么快就知道答案了"
  • A : "只要在8的基础上加1就行了"
  • A : "所以你不用重新计算,因为你记住了第一个等式的值为8!动态规划算法也可以说是 '记住求过的解来节省时间'"

问题举例:70. 爬楼梯 

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

输入:n = 3
输出:3
解释:有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶
3. 2 阶 + 1 阶

方法1:带备忘录的递归解法

方法2:自底向上的动态规划

动态规划典型特征:最优子结构、状态转移方程、边界、重叠字问题

  • f(n-1)和f(n-2) 称为 f(n) 的最优子结构
  • f(n)= f(n-1)+f(n-2)就称为状态转移方程
  • f(1) = 1, f(2) = 2 就是边界啦
  • 比如f(10)= f(9)+f(8),f(9) = f(8) + f(7) ,f(8)就是重叠子问题。

什么样的问题适合用动态规划?

如果一个问题,可以把所有可能的答案穷举出来,并且穷举出来后,发现存在重叠子问题,就可以考虑使用动态规划。

一道动态规划问题,其实就是一个递推问题。假设当前决策结果是f(n),则最优子结构就是要让 f(n-k) 最优,最优子结构性质就是能让转移到n的状态是最优的,并且与后面的决策没有关系,即让后面的决策安心地使用前面的局部最优解的一种性质。

问题举例:现有一个整数数组 nums ,找到其中最长严格递增子序列的长度。

输入:nums = [10,9,2,5,3,7,101,18]
输出:4
解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。

 

高数Umaru系列(9)——哈士奇

Description

由于高数巨养的喵星人太傲娇了,要天天吃新鲜猫粮而且还经常欺负高数巨,所以高数巨决定买几条哈士奇尝尝鲜。这天高数巨来到了二手狗市场买哈士奇,高数巨看完了所有的哈士奇,记下了每条哈士奇的价格,并根据对它们的好感程度给它们每只都赋予了一个萌值。高数现在手里有X元,她想通过购买若干条哈士奇来获得尽可能多的萌值。现在给定高数巨手里的钱X以及N条哈士奇的价格和萌值,求高数巨最多可获得多少萌值

Input

 多组输入。

对于每组输入,第一行有两个整数N,X(1 < = N < = 100,1 < = X < = 1000),分别表示哈士奇的数量和高数巨的钱数

接下来的N行每行有两个整数Pi,Mi(1 < = Pi,Mi < = 100),分别表示第i条哈士奇的价格和萌值

Output

对于每组数据,输出一个整数,表示高数巨最多可以获得的萌值,每组输出占一行

Samples

Sample #1

Input 
Output 
2 100
50 20
60 40
3 100
20 55
20 35
90 95
1 10
20 50
40
95
0
 1 #include<stdio.h>
 2 #include<string.h>
 3 
 4 int max(int x, int y)
 5 {
 6     if(x>y) return x;
 7     else return y;
 8 }
 9 
10 int main()
11 {
12     int p[105], m[105], a[105][1005], n, x, i, j;
13     while(~scanf("%d %d", &n, &x))
14     {
15         for(i=1;i<=n;i++) // 从1开始,因为0是边界也是值!因为这里Wa了10+次
16         {
17             scanf("%d %d", &p[i], &m[i]);
18         }
19         memset(a, 0, sizeof(a)); // 每次都需要初始化
20 
21         for(i=1;i<=n;i++) // 第几个哈士奇
22         {
23             for(j=1;j<=x;j++) // 价钱
24             {
25                 if(p[i] <= j) // 买得起,可以买,也可以不买
26                     a[i][j] = max(a[i-1][j], a[i-1][j-p[i]] + m[i]);
27                 else a[i][j] = a[i-1][j]; // 买不起,就不买
28             }
29         }
30         printf("%d\n", a[n][x]);
31     }
32     return 0;
33 }

 

 

 
posted @ 2024-05-08 20:15  Xxiaoyu  阅读(4)  评论(0编辑  收藏  举报