洛谷 P1544 三倍经验 【记忆化搜索】

洛谷 P1544 三倍经验 【记忆化搜索】三倍经验 传送门 P1544 三倍经验 题目描述 数字金字塔由 n n n 行整数组成 第 i 1 i n

大家好,我是讯享网,很高兴认识大家。

三倍经验

传送门:P1544 三倍经验

题目描述

数字金字塔由 n n n 行整数组成,第 i ( 1 ≤ i ≤ n ) i(1\le i\le n) i(1in) 行有 i i i 个数字,一个示例如下。

 7 3 9 8 1 0 2 7 4 4 4 5 2 6 5 

讯享网

现在你在金字塔的顶部(第一行),你希望走到金字塔的底部(第 n n n 行),每一步你只能走向当前所在位置的左下方的数字或者右下方的数字。同时作为一个强大的小朋友,你可以选择金字塔中的不多于 k k k 个数字让他们成为原来的 3 3 3 倍。

你会收集你路上经过的所有位置上的数字,最后的得分即为收集的数字之和,求最大得分。

输入格式

第一行输入两个整数 n , k n,k n,k,表示数字金字塔的行数和乘 3 3 3 的数字个数最大值;
接下来 n n n 行,其中的第 i i i 行有 i i i 个以空格隔开的整数依次表示数字金字塔第 i i i 行的数字 a i , 1 , a i , 2 , a i , 3 . . . a i , i a_{i,1},a_{i,2},a_{i,3}...a_{i,i} ai,1,ai,2,ai,3...ai,i

输出格式

一行一个整数,表示最大得分。

样例 #1

样例输入 #1

讯享网5 3 7 3 9 8 1 0 2 7 4 4 4 5 2 6 5 

样例输出 #1

75 

提示

对于 30 % 30\% 30% 的数据,满足 k ≤ n ≤ 6 k\le n\le 6 kn6,并且对于任意 1 ≤ i ≤ n 1\le i\le n 1in 1 ≤ j ≤ i 1\le j\le i 1ji 满足 0 ≤ a i , j ≤ 100 0\le a_{i,j}\le 100 0ai,j100
对于 100 % 100\% 100% 的数据,满足 1 ≤ n ≤ 100 1\le n\le100 1n100 0 ≤ k ≤ n ( n + 1 ) 2 0\le k\le \dfrac{n(n+1)}{2} 0k2n(n+1),且对于任意 1 ≤ i ≤ n 1\le i\le n 1in 1 ≤ j ≤ i 1\le j\le i 1ji 满足 ∣ a i , j ∣ ≤ 1 0 9 |a_{i,j}|\le 10^9 ai,j109

解题思路

这道题目可以使用记忆化搜索和动态规划求解,本文给出记忆化搜索解法:


讯享网

定义一个二维数组a存放数字金字塔,一个三维计数数组cnt 统计经过路径数字总值。使用mark三维数组进行是否遍历过的标记。

初始化cnt中的每个值为最小值(避免判断最小值时出错),从最顶部数开始搜索。

若超出范围,返回0

若已经搜索过,则直接返回值。

如果还有修改次数,则还可进行修改,依次选择左边或者右边的数(分类讨论,取最大值);次数用尽则不能再修改。

再写出不修改的情况,分类讨论,取最大值,标记已访问,返回结果。

解题代码:

讯享网import java.io.*; import java.util.Arrays; public class Main { 
    static StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in))); static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out)); static int n,k; static long ans; static long [][] a = new long[105][105]; static long [][][] cnt = new long[105][105][105]; static long [][][] mark = new long[105][105][105]; public static void main(String[] args) throws IOException { 
    n = nextInt(); k = nextInt(); if(k>n)k = n; for (int i = 1; i <=n ; i++) { 
    for (int j = 1; j <=i ; j++) { 
    a[i][j] = nextLong(); } } //初始化 for(long[][] k:cnt){ 
    for(long[] t:k){ 
    Arrays.fill(t,Long.MIN_VALUE); } } ans = dfs(1,1,0); out.println(ans); out.flush(); } public static long dfs(int x,int y,int p){ 
    if(x<1 || x>n || y<1 || y>n) return 0;//越界 if(mark[x][y][p]==1){ 
    return cnt[x][y][p]; } if(p<k){ 
   //还有修改次数 cnt[x][y][p] = Math.max(cnt[x][y][p],dfs(x+1,y,p+1)+a[x][y]*3L);//选左边 cnt[x][y][p] = Math.max(cnt[x][y][p],dfs(x+1,y+1,p+1)+a[x][y]*3L);//选右边 } //分类讨论 cnt[x][y][p] = Math.max(cnt[x][y][p],dfs(x+1,y,p)+a[x][y]);//没修改 cnt[x][y][p] = Math.max(cnt[x][y][p],dfs(x+1,y+1,p)+a[x][y]); mark[x][y][p] = 1;//已访问 return cnt[x][y][p]; } public static int nextInt() throws IOException{ 
    in.nextToken(); return (int)in.nval; } public static long nextLong() throws IOException{ 
    in.nextToken(); return (long)in.nval; } } 

如果本文对你有帮助,可以点个赞噢!

小讯
上一篇 2025-03-15 13:54
下一篇 2025-03-06 12:49

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/62113.html