题目描述:
给你两个整数 num 和 k ,考虑具有以下属性的正整数多重集:
每个整数个位数字都是 k 。
所有整数之和是 num 。
返回该多重集的最小大小,如果不存在这样的多重集,返回 -1 。
注意:
多重集与集合类似,但多重集可以包含多个同一整数,空多重集的和为 0 。
个位数字 是数字最右边的数位。
思路:
1、将所有个位数字为k的数初始化出来,总共300个,(num最大3000)
2、然后每个数字是一个物品的容量,物品的消耗为1
3、背包的总容量为num,于是就转变为一个 完全背包 问题,求完全背包的容量为num的最小消耗
class Solution {
int pack[310],packsize;
public:
int minimumNumbers(int num, int k) {
packsize = 0;
int dp[3010];
//将所有个位数字为k的数初始化出来,总共300个
for (int i = 0; i <= num; ++i) {
if (i % 10 == k) {
pack[++packsize] = i;
}
}
for (int j = 0; j <= num; ++j) {
dp[j] = 100000000;
}
dp[0] = 0;
for (int i = 1; i <= packsize; ++i) {
for (int j = pack[i]; j <= num; ++j) {
//dp[j - pack[i]] + 1 表示前i个数组合出j,所需要的数字的最小个数
if (dp[j - pack[i]] + 1 < dp[j]) {
dp[j] = dp[j - pack[i]] + 1;
}
}
}
return dp[num] >= 100000000 ? -1:dp[num];
}
};
题目描述:
给你一个大小为 rows x cols 的矩阵 grid 。最初,你位于左上角 (0, 0) ,每一步,你可以在矩阵中 向右 或 向下 移动。
在从左上角 (0, 0) 开始到右下角 (rows - 1, cols - 1) 结束的所有路径中,找出具有 最大非负积 的路径。路径的积是沿路径访问的单元格中所有整数的乘积。
返回 最大非负积 对 109 + 7 取余 的结果。如果最大积为负数,则返回 -1 。
注意,取余是在得到最大积之后执行的
思路:
1、用户dpmin[i][j]记录从(0,0)点到(i,j)点的最小乘积,用dpmax[i][j]记录从(0,0)点到(i,j)点的最大乘积,每次都需要求最大值和最小值,因为可能是负数,最后取最大值即可。
2、每次状态转移可以从左边来,或者从上边来,于是进行m*n的状态转移以后,得到dpmax[m-1][n-1]的值就是最后的答案了,如果它小于0,则输出-1,别忘了取模
class Solution {
#define ll long long
ll dpmin[16][16], dpmax[16][16];
ll getmin(int now, int i, int j) {
return min(dpmin[i][j]*now, dpmax[i][j]*now);
}
ll getmax(int now, int i, int j) {
return max(dpmin[i][j]*now, dpmax[i][j]*now);
}
public:
int maxProductPath(vector<vector<int>>& grid) {
int m = grid.size();
int n = grid[0].size();
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (!i & !j) { //i=j=0,初始化dpmax和dpmin
dpmax[i][j] = dpmin[i][j] = grid[i][j];
} else if(!i) { //i=0时只能从上面下来
dpmax[i][j] = getmax(grid[i][j], i, j-1);
dpmin[i][j] = getmin(grid[i][j], i, j-1);
} else if(!j) {//j=0时只能从左边下来
dpmax[i][j] = getmax(grid[i][j], i-1, j);
dpmin[i][j] = getmin(grid[i][j], i-1, j);
} else {
dpmax[i][j] = getmax(grid[i][j], i, j-1);
dpmax[i][j] = max(dpmax[i][j], getmax(grid[i][j], i-1, j));
dpmin[i][j] = getmin(grid[i][j], i, j-1);
dpmin[i][j] = min(dpmin[i][j], getmin(grid[i][j], i-1, j));
}
}
}
if (dpmax[m-1][n-1] < 0) return -1;
else return dpmax[m-1][n-1]%1000000007;
}
};