这些题目的难度是递增顺序来的,后续慢慢再补
第一题(牛妹的蛋糕)
题目描述
众所周知,牛妹非常喜欢吃蛋糕。
第一天牛妹吃掉蛋糕总数三分之一(向下取整)多一个,第二天又将剩下的蛋糕吃掉三分之一(向下取整)多一个,以后每天吃掉前一天剩下的三分之一(向下取整)多一个,到第n天准备吃的时候只剩下一个蛋糕。
牛妹想知道第一天开始吃的时候蛋糕一共有多少呢?
示例1
输入
复制
2
返回值
复制
3
思路:
1.(数学分析)首先假设第一天准备开始吃的时候有x份蛋糕,那么第二天准备开始吃的时候的蛋糕 x-(x*1/3 + 1) = x * 2/3 - 1 份蛋糕。
2.(找状态方程)设dp[i]为第i天准备开始吃的时候有dp[i]份蛋糕,那么第二天准备开始吃的时候的蛋糕就为dp[i+1];根据1的分析可得 dp[i+1] = dp[i] * 2/3 - 1;
3.因为题目给定的n代表的是,最后一天她正准备吃的时候剩下的数量,我们要根据这个数量往前推出她第一天的蛋糕数。所以可得方程式dp[i] = 3 * (dp[i+1]+1) / 2; (就是2中的方程变形)。
完事写代码
#include<iostream>
using namespace std;
int cakeNumber(int n) {
int dp = 1;
for(int i = n - 1; i >= 1; --i)
{
dp = 3 * (dp + 1) / 2;
}
return dp;
}
int main()
{
int n;
cin >> n;
cout << cakeNumber(n);
return 0;
}
第二题(牛妹的礼物)
题目描述
众所周知,牛妹有很多很多粉丝,粉丝送了很多很多礼物给牛妹,牛妹的礼物摆满了地板。
地板是N\times MN×M的格子,每个格子有且只有一个礼物,牛妹已知每个礼物的体积。
地板的坐标是左上角(1,1) 右下角(N, M)。
牛妹只想要从屋子左上角走到右下角,每次走一步,每步只能向下走一步或者向右走一步或者向右下走一步
每次走过一个格子,拿起(并且必须拿上)这个格子上的礼物。
牛妹想知道,她能走到最后拿起的所有礼物体积最小和是多少?
思路
首先把题目给定的礼物体积存入一个二维数组A[MAX][MAX]中,然后准备开始动态规划了。设一个二维数组dp[MAX][MAX],先初始化计算它的第一行第一列,因为第一行第一列的所有数据只能是通过它的前一个数据得来,初始完之后,计算其他的。
状态方程 :dp[i][j] = min(dp[i-1][j-1],min(dp[i][j-1],dp[i-1][j])) + A[i][j];
就是判断当前点的向上一个数据,向左的一个数据,左上的一个数据,这三个数据的最小值再加上当前的体积值就是该点的值。
完事写代码
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
#define MAX 1100
int dp[MAX][MAX],A[MAX][MAX];
int main()
{
int m,n;
cin >> n >> m;
for(int i = 1; i <= n; ++i){
for(int j = 1; j <= m; ++j){
cin >> A[i][j];
dp[i][j] = 0;
}
}
dp[1][1] = A[1][1