首页 > 其他分享 >20240709

20240709

时间:2024-07-14 18:52:17浏览次数:6  
标签:p2 p1 int max 20240709 305 dp

T1

NFLSOJ P3372 game

考虑对于 B 的行动,A 会采取怎样的策略。容易发现两人路线相交只会是一条线段,因此枚举这条线段在 B 走过的哪条线段上,记录从起点和终点分别走到每个位置的最大权值,就可以搞了。然后考虑对 B 的路径 dp,\(dp[i][j][0/ 1]\) 表示从 B 的起点走到 \((i, j)\),最后一步是怎么过来的 这样 A 最大的最小收益。转移枚举从上面还是右边的哪个位置过来,对这一段路径算出 A 的最优收益,与前面的 dp 值取 \(\max\) 再与当前位置取 \(\min\) 转移。最优收益可以一边枚举位置一边算。与前面的 dp 值取 \(\max\) 是因为选择从 B 走过的哪一段路上过是 A 的决策,与当前 dp 值取 \(\min\) 是因为从哪个位置过来是 B 的决策。

这个 dp 的本质实际上是对于每条路径计算权值,计算的方法是把所有经过当前线段的合并计算,然后由于这些路径走到当前点的所有方案都被算过了,它们就是同一个状态了,会一起参与之后的计算。

代码
#include <iostream>
#include <string.h>
#define int long long
using namespace std;
int a[305][305];
int p1[305][305];
int p2[305][305];
int dp[305][305][2];
int n, m;
signed main() {
    freopen("game.in", "r", stdin);
    freopen("game.out", "w", stdout);
    int tc;
    cin >> tc;
    while (tc--) {
        memset(p1, 0, sizeof p1);
        memset(p2, 0, sizeof p2);
        cin >> n >> m;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                cin >> a[i][j];
                p1[i][j] = max(p1[i - 1][j], p1[i][j - 1]) + a[i][j];
            }
        }
        for (int i = n; i; i--) {
            for (int j = m; j; j--) 
                p2[i][j] = max(p2[i + 1][j], p2[i][j + 1]) + a[i][j];
        }
        memset(dp, 63, sizeof dp);
        int mx=p1[1][m-1];
        for(int i=2;i<=n;i++) {
            dp[i][m][1] = min(dp[i][m][1], mx+p2[i+1][m]);
            mx = max(mx, p1[i][m-1]);
        }
        mx=p2[2][m];
        for(int i=m-1;i>=1;i--) {
            dp[1][i][0] = min(dp[1][i][0],mx+p1[1][i-1]);
            mx = max(mx,p2[2][i]);
        }
        for (int i = 1; i <= n; i++) {
            for (int j = m; j; j--) {
                int mxv = 0;
                for (int k = i + 1; k <= n; k++) {
                    int tmp;
                    tmp = max(mxv, max(p2[k + 1][j], p2[k][j + 1]) + p1[k - 1][j - 1]);
                    tmp = max(tmp, p1[i - 1][j] + max(p2[k][j + 1], p2[k + 1][j]));
                    dp[k][j][1] = min(dp[k][j][1], max(dp[i][j][0], tmp));
                    mxv = max(mxv, p2[k][j + 1] + p1[k][j - 1]);
                }
                mxv = 0;
                for (int k = j - 1; k; k--) {
                    int tmp;
                    tmp = max(mxv, max(p1[i - 1][k], p1[i][k - 1]) + p2[i + 1][k + 1]);
                    tmp = max(tmp, p2[i][j + 1] + max(p1[i - 1][k], p1[i][k - 1]));
                    dp[i][k][0] = min(dp[i][k][0], max(dp[i][j][1], tmp));
                    mxv = max(mxv, p2[i + 1][k] + p1[i - 1][k]);
                }
            }
        }
        cout << min(dp[n][1][0], dp[n][1][1]) << "\n";
    }
    return 0;
}

标签:p2,p1,int,max,20240709,305,dp
From: https://www.cnblogs.com/forgotmyhandle/p/18301874

相关文章

  • 坐牢第五天加第六天 20240709
    作业1、提示并输入一个字符串,统计该字符串中字母、数字、空格以及其他字符的个数代码:​#include<stdio.h>#include<string.h>intmain(intargc,charconst*argv[]){chararr[100];inta,c,d,e=0;printf("请输入一个字符串:");gets(arr);f......
  • 20240709(byte数据转换、字典数据选择性保留、选择性查询数据库)
    需要补的知识:​ 1.HTTP协议,url里,那些header、body里都是啥东西报错信息:"服务异常'bytes'objecthasnoattribute'get'"错误原因:​ http传输中,GET方法传入的是byte格式的数据,没有.get方法#假设你有一个包含JSON数据的字节字符串json_bytes=b'{"name":"John",&quo......
  • 20240709比赛总结
    T1超市抢购https://gxyzoj.com/d/hzoj/p/3765仔细读懂数据生成器,就能看出来,实际上物品肯定是够用的因为只能从右向左搬运物品,所以我们只需要对于每一个i,i+1的间隔,考虑有多少个物资需要从右边搬到左边去,把这个贡献累加即可代码:#include<cstdio>#include<algorithm>#define......
  • 【20240709】海量图片导出需求,shell脚本
     [root@localhostimages]#catjunshuv3.sh#!/bin/bash#确保脚本在~/images目录下运行if["$(pwd)"!="$HOME/images"];thencd~/imagesfi#创建目标目录junshu,如果不存在则创建mkdir-pjunshu#获取CSV文件中的总行数,用于进度条total_lines=$(wc-l......