• P1216 [IOI1994][USACO1.5]数字三角形 Number Triangles


    P1216 [IOI1994][USACO1.5]数字三角形 Number Triangles

    这个题吧,之前学DP的时候就做过一次了,其实还是挺简单的,如果一步一步按照找状态定义,找边界条件,找转移方程的话,不失为一道好题,我们就就这题复习一下DP,然后顺便讲点别的

    因为我们是从顶点开始走,往左下走或者右下走,所以我们的状态就是F[i][j]我们停在第i行第j列所能达到的最大权值

    对于每一个点,我们看他是从哪一个点过来的,可以是右上面也可以是左上面

     转移方程:f[i][j]=max(f[i-1][j-1]+f[i-1][j])+a[i][j]

    QWQ终于是有一个能码出来的代码了

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int r,a[1001][1001],qaq[1001][1001],MAX;
    int main() {
        cin>>r;
        for(int i=1; i<=r; ++i)//第i行第j个
            for(int j=1; j<=i; ++j)
                cin>>a[i][j];
        for(int i=1; i<=r; ++i)
            for(int j=1; j<=i; ++j) {
                qaq[i][j]=max(qaq[i-1][j-1],qaq[i-1][j])+a[i][j];
            }
        for(int i=1; i<=r; ++i)
            MAX=max(MAX,qaq[r][i]);
            cout<<MAX;
        return 0;
    }

    改造题目(EX NumberTriangles)

    我们要使得找出来的权值和%m之后的值是最大的,

    起初我的想法是用一个结构体来存实际权值和取模后的权值,但是是不行的,因为不再满足最优子结构原则了。(就是说实际权值和取模权值之间的大小没有必然联系,所以我们无法用状态转移方程来求最大最小)

    我们考虑加一个维度,开一个bool数组f

    f[i][j][k]代表走到第i行第j列是路径权值和%m=  k    可不可能,那我们怎么转移呢

    还是考虑一个点只有可能从它的左上方和右上方求值过来,那么我们就能得出状态转移方程了

    f[i][j][k] = f[i - 1][j - 1][(k - a[i][j]) % m] || f[i - 1][j][(k - a[i][j]) % m]
    边界情况的话,就是
    f[1][1][a[1][1] % m] = true(按照状态的定义来理解就行,很好理解)
    然后我们就遍历一遍最终结果就可以了
    for (int i = 1; i <= n; ++i)
        {
            for (int j = 1; j <= m; ++j)
            {
                if (f[n][i][j])
                    ans = max(ans, j);
            }
        }

    就这样,完事(大雾)

  • 相关阅读:
    正则表达式
    JavaIO详解
    Java集合类详解
    Java虚拟机原理图解
    关于Java中按值传递和按引用传递的问题详解
    图的建立(邻接矩阵)+深度优先遍历+广度优先遍历+Prim算法构造最小生成树(Java语言描述)
    The 70th problem,UVa10396 Vampire Numbers
    二叉树的实现(Java语言描述)
    编程之路
    AngularJS 开发中常犯的10个错误
  • 原文地址:https://www.cnblogs.com/this-is-M/p/10797869.html
Copyright © 2020-2023  润新知