• 洛谷


    https://www.luogu.org/problemnew/show/P1004

    这道题分类到简单dp但是感觉一点都不简单……这种做两次的dp真的不是很懂怎么写。假如是贪心做两次,感觉又不能证明这是最优的。

    直接看题解,题解要设置4个维度,两个人同时走……但是怎么避免同一个物品被两个人拿呢?

    设置dp[i][j][k][l]表示第1个人走到ij,第2个人走到kl能实现的最大的取法,再加一维[p]表示现在已经取了00,01,02,10,11,12,20,21,22个物品,然后dp的内容是一个vector!这样就完美地表达了所有信息了!这样同一个物品只会让一个状态转移到另一个状态,保证不会让这个物品同时被取到!空间复杂度?我为什么要管空间复杂度?这个dp时间复杂度都是和空间复杂度同阶的……省那一点干嘛呢……

    好了看了别人的状态设置,找到一个思路,先自己写试试看……

    写个鬼哦我去,读错题了,不是只能拿两个物品……我又该睡觉了……

    注意两个人是同时走的!假设不是两个人同时走的,那会怎么样呢?那样不仅复杂度上升了n²,而且不能判断当前格子是不是被另一个人的路取过了

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    
    int dp[10][10][10][10];
    int a[10][10];
    
    int main(){
        int n;
        scanf("%d",&n);
        int x,y,v;
        while(1){
            scanf("%d%d%d",&x,&y,&v);
            if(x==0&&y==0&&v==0)
                break;
            a[x][y]=v;
        }
    
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                for(int k=1;k<=n;k++){
                    for(int l=1;l<=n;l++){
                        dp[i][j][k][l]=max(max(dp[i-1][j][k-1][l],dp[i-1][j][k][l-1]),max(dp[i][j-1][k-1][l],dp[i][j-1][k][l-1]));
                        dp[i][j][k][l]+=a[i][j];
                        if(i==k&&j==l)
                            ;
                        else
                            dp[i][j][k][l]+=a[k][l];
                    }
                }
            }
        }
        printf("%d
    ",dp[n][n][n][n]);
    }

    别人的题解说后面还有传纸条和回文的路径,也是这种两边一起做的dp。

  • 相关阅读:
    没有什么,开发ASP.NET时随便写写,想到什么写什么
    MS SQL Server带有时间的记录怎样查询
    给RadioButtonList绑定Selected的值
    在GridView控件内文本框实现TextChanged事件
    MS SQL Server递归查询
    ASP.NET MVC使用jQuery无刷新上传
    MySQL 慢查询操作梳理
    ubuntu系统下防火墙简单使用
    crontab日常使用梳理
    ubuntu下nginx+php5的部署
  • 原文地址:https://www.cnblogs.com/Yinku/p/10325524.html
Copyright © 2020-2023  润新知