版权声明:转载请注明原址,有错误欢迎指出 https://blog.csdn.net/iwts_24/article/details/83502104
题目链接
LeetCode 周赛 108场 C题
https://leetcode-cn.com/contest/weekly-contest-108/problems/minimum-falling-path-sum/
题意
比较简单的,也就是说上一层下降的话只能间隔1位下降,例如下图:
看懂给的例子就理解题意了。
题解
C题着实感觉自己脑子不太灵光了QAQ,总是在不坑的题上坑。刚开始就想着用DFS爽的一匹,果断超时。剪枝以后还是超时。直接忘记了因为递归比较费时间,既然能DFS了,那反向操作用数组存最小值直接改成DP岂不稳得一匹?然后就跑去写D题了,当时根本没想到DP还以为有什么剪枝没想到。。。
如果是DP的话其实就是比较简单的求和DP反向写。开二维数组,存第一行的所有数,从第二行开始,找每个位置能从上一行哪些位置下降过来,将其中的最小值赋值就可以了。其实就是上面的图,将指向反过来看就可以了:
那么除了两端的特殊情况,其他都是能从3个位置下降过来,有状态转移方程:
dp[i][j] = A[i][j] + Min(dp[i-1][j-1],dp[i-1][j],dp[i-1][j+1])
注意判定最左边和最右边两种情况就行了。
另外,竟然破天荒给了数据范围,当n = 1的时候只有一个下降数组就是本身,这个判定一下就行。最终答案要for循环遍历一下最下面一层,看最小值是多少。最小值就是答案。
Java 代码
class Solution {
public static int[][] dp;
public static int Min(int a,int b){
return a < b ? a : b;
}
public int minFallingPathSum(int[][] A) {
int len = A[0].length;
if(len == 1) return A[0][0];
dp = new int[len][len];
for(int i = 0;i < len;i++){
dp[0][i] = A[0][i];
}
for(int i = 1;i < len;i++){
for(int j = 0;j < len;j++){
if(j == 0){
dp[i][j] = A[i][j] + Min(dp[i-1][j],dp[i-1][j+1]);
}else{
if(j == len-1){
dp[i][j] = A[i][j] + Min(dp[i-1][j],dp[i-1][j-1]);
}else{
dp[i][j] = A[i][j] + Min(Min(dp[i-1][j],dp[i-1][j+1]),dp[i-1][j-1]);
}
}
}
}
int ans = 20000;
for(int i = 0;i < len;i++){
ans = Min(ans,dp[len-1][i]);
}
return ans;
}
}
DFS
纪念一下日常智障操作,TLE代码:
class Solution {
public static int ans;
public static int limit;
public static void solve(int line,int index,int val,int[][] temp){
if(line == limit-1){
ans = ans > val ? val : ans;
return;
}
if(val - 100*(limit-1-line) >= ans) return;
solve(line+1,index,val+temp[line+1][index],temp);
if(index == 0){
solve(line+1,index+1,val+temp[line+1][index+1],temp);
}else{
if(index == limit-1){
solve(line+1,index-1,val+temp[line+1][index-1],temp);
}else{
solve(line+1,index+1,val+temp[line+1][index+1],temp);
solve(line+1,index-1,val+temp[line+1][index-1],temp);
}
}
}
public int minFallingPathSum(int[][] A) {
ans = 20000;
limit = A[0].length;
if(limit == 1) return A[0][0];
for(int i = 0;i < limit;i++){
solve(0,i,A[0][i],A);
}
return ans;
}
}