首页 > 其他分享 >F - Earn to Advance

F - Earn to Advance

时间:2024-03-10 16:56:59浏览次数:22  
标签:Advance Earn square int 1000000000 leq His money

F - Earn to Advance

Problem Statement

There is a grid with $N$ rows and $N$ columns. Let $(i,j)$ denote the square at the $i$-th row from the top and $j$-th column from the left.

Takahashi is initially at square $(1,1)$ with zero money.

When Takahashi is at square $(i,j)$, he can perform one of the following in one action:

  • Stay at the same square and increase his money by $P_{i,j}$.
  • Pay $R_{i,j}$ from his money and move to square $(i,j+1)$.
  • Pay $D_{i,j}$ from his money and move to square $(i+1,j)$.

He cannot make a move that would make his money negative or take him outside the grid.

If Takahashi acts optimally, how many actions does he need to reach square $(N,N)$?

Constraints

  • $2 \leq N \leq 80$
  • $1 \leq P_{i,j} \leq 10^9$
  • $1 \leq R_{i,j},D_{i,j} \leq 10^9$
  • All input values are integers.

Input

The input is given from Standard Input in the following format:

$N$
$P_{1,1}$ $\ldots$ $P_{1,N}$
$\vdots$
$P_{N,1}$ $\ldots$ $P_{N,N}$
$R_{1,1}$ $\ldots$ $R_{1,N-1}$
$\vdots$
$R_{N,1}$ $\ldots$ $R_{N,N-1}$
$D_{1,1}$ $\ldots$ $D_{1,N}$
$\vdots$
$D_{N-1,1}$ $\ldots$ $D_{N-1,N}$

Output

Print the answer.


Sample Input 1

3
1 2 3
3 1 2
2 1 1
1 2
4 3
4 2
1 5 7
5 3 3

Sample Output 1

8

Figure

It is possible to reach square $(3,3)$ in eight actions as follows:

  • Stay at square $(1,1)$ and increase money by $1$. His money is now $1$.
  • Pay $1$ money and move to square $(2,1)$. His money is now $0$.
  • Stay at square $(2,1)$ and increase money by $3$. His money is now $3$.
  • Stay at square $(2,1)$ and increase money by $3$. His money is now $6$.
  • Stay at square $(2,1)$ and increase money by $3$. His money is now $9$.
  • Pay $4$ money and move to square $(2,2)$. His money is now $5$.
  • Pay $3$ money and move to square $(3,2)$. His money is now $2$.
  • Pay $2$ money and move to square $(3,3)$. His money is now $0$.

Sample Input 2

3
1 1 1
1 1 1
1 1 1
1000000000 1000000000
1000000000 1000000000
1000000000 1000000000
1000000000 1000000000 1000000000
1000000000 1000000000 1000000000

Sample Output 2

4000000004

 

解题思路

  要求 $(1,1) \to (n,n)$ 的最小操作次数,不妨先考虑最后一次使用第一种操作的位置,假设为 $(i,j)$。为了保证 $(i,j) \to (n,n)$ 不存在金额为负数的情况,需要在 $(i,j)$ 处停留一定的次数。假设 $h(i,j,n,n)$ 表示 $(i,j) \to (n,n)$ 的所有路径中只执行第二、三种操作的最小金额,$g(i,j)$ 表示 $(1,1) \to (i,j)$ 还剩的金额,那么在 $(i,j)$ 处至少要停留 $c = \left\lceil \frac{\max\{{0, \, h(i,j,n,n) - g(i,j)}\}}{p_{i,j}} \right\rceil$ 次。因此当 $(i,j)$ 是最后一次使用第一种操作的位置时,$(i,j) \to (n,n)$ 的最小操作次数就是 $c + n-i + n-j$。

  现在问题就变成了求 $(1,1) \to (i,j)$ 的最小操作次数,显然可以沿用上面的思路。为此可以考虑 dp,定义 $f(i,j)$ 表示 $(1,1) \to (i,j)$ 的最小操作次数,根据最后一次使用第一种操作的位置 $\{ (u,v) \mid 1 \leq u \leq i, 1 \leq v \leq j \}$ 进行状态划分,状态转移方程就是 $f(i,j) = \min\limits_{(u,v)}\left\{{f(u,v) + c + i-u + j-v}\right\}$,其中 $c = \left\lceil \frac{\max\{{0, \, h(u,v,i,j) - g(u,v)}\}}{p_{u,v}} \right\rceil$。

  考虑维护 $g(i,j)$ 的最大值,当 $f(i,j) > f(u,v) + c + i-u + j-v$ 时,直接令 $g(i,j) = g(u,v) + c \cdot p_{u,v} - h(u,v,i,j)$。否则如果 $f(i,j) = f(u,v) + c + i-u + j-v$,$g(i,j) = \max\{{g(i,j), \, g(u,v) + c \cdot p_{u,v} - h(u,v,i,j)}\}$。

  $h(i,j,u,v)$ 可以用 dp 预处理出来,状态转移方程就是 $h(i,j,u,v) = \min\left\{h(i,j,u-1,v) + d_{u-1,v}, \, h(i,j,u,v-1) + r_{u,v-1}\right\}$。

  AC 代码如下,时间复杂度为 $O(n^4)$:

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const int N = 85;

int p[N][N], r[N][N], d[N][N];
LL f[N][N], g[N][N], h[N][N][N][N];

int main() {
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            scanf("%d", &p[i][j]);
        }
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j < n; j++) {
            scanf("%d", &r[i][j]);
        }
    }
    for (int i = 1; i < n; i++) {
        for (int j = 1; j <= n; j++) {
            scanf("%d", &d[i][j]);
        }
    }
    memset(h, 0x3f, sizeof(h));
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            h[i][j][i][j] = 0;
            for (int u = i; u <= n; u++) {
                for (int v = j; v <= n; v++) {
                    if (u == i && v == j) continue;
                    h[i][j][u][v] = min(h[i][j][u - 1][v] + d[u - 1][v], h[i][j][u][v - 1] + r[u][v - 1]);
                }
            }
        }
    }
    memset(f, 0x3f, sizeof(f));
    f[1][1] = 0;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            for (int u = 1; u <= i; u++) {
                for (int v = 1; v <= j; v++) {
                    LL c = (max(0ll, h[u][v][i][j] - g[u][v]) + p[u][v] - 1) / p[u][v];
                    if (f[i][j] > f[u][v] + c + i - u + j - v) {
                        f[i][j] = f[u][v] + c + i - u + j - v;
                        g[i][j] = g[u][v] + p[u][v] * c - h[u][v][i][j];
                    }
                    else if (f[i][j] == f[u][v] + c + i - u + j - v) {
                        g[i][j] = max(g[i][j], g[u][v] + p[u][v] * c - h[u][v][i][j]);
                    }
                }
            }
        }
    }
    printf("%lld", f[n][n]);
    
    return 0;
}

  上面代码所需的内存是 $400 \text{ MB}$ 左右。还可以把 $h$ 优化到两维。在枚举 $(i,j)$ 的时候定义 $h(u,v)$ 表示 $(u,v) \to (i,j)$ 只执行第二、三种操作的最小金额。状态转移方程就是 $h(u,v) = \min\left\{{h(u+1,v) + d_{u,v}, \, h(u,v+1) + r_{u,v}}\right\}$。

  AC 代码如下,时间复杂度为 $O(n^4)$:

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const int N = 85;

int p[N][N], r[N][N], d[N][N];
LL f[N][N], g[N][N], h[N][N];

int main() {
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            scanf("%d", &p[i][j]);
        }
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j < n; j++) {
            scanf("%d", &r[i][j]);
        }
    }
    for (int i = 1; i < n; i++) {
        for (int j = 1; j <= n; j++) {
            scanf("%d", &d[i][j]);
        }
    }
    memset(f, 0x3f, sizeof(f));
    f[1][1] = 0;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            memset(h, 0x3f, sizeof(h));
            h[i][j] = 0;
            for (int u = i; u; u--) {
                for (int v = j; v; v--) {
                    if (u == i && v == j) continue;
                    h[u][v] = min(h[u + 1][v] + d[u][v], h[u][v + 1] + r[u][v]);
                }
            }
            for (int u = 1; u <= i; u++) {
                for (int v = 1; v <= j; v++) {
                    LL c = (max(0ll, h[u][v] - g[u][v]) + p[u][v] - 1) / p[u][v];
                    if (f[i][j] > f[u][v] + c + i - u + j - v) {
                        f[i][j] = f[u][v] + c + i - u + j - v;
                        g[i][j] = g[u][v] + p[u][v] * c - h[u][v];
                    }
                    else if (f[i][j] == f[u][v] + c + i - u + j - v) {
                        g[i][j] = max(g[i][j], g[u][v] + p[u][v] * c - h[u][v]);
                    }
                }
            }
        }
    }
    printf("%lld", f[n][n]);
    
    return 0;
}

 

参考资料

  Editorial - Toyota Programming Contest 2024#3(AtCoder Beginner Contest 344):https://atcoder.jp/contests/abc344/editorial/9494

标签:Advance,Earn,square,int,1000000000,leq,His,money
From: https://www.cnblogs.com/onlyblues/p/18064351

相关文章

  • Bootstrap Your Own Latent A New Approach to Self-Supervised Learning论文阅读笔记
    BootstrapYourOwnLatentANewApproachtoSelf-SupervisedLearning论文阅读笔记Abstract​ 我们提出了BYOL,一种新的自监督图像表示学习的方法。BYOL依赖于两个神经网络,即在线网络和目标网络,它们相互作用和相互学习。从一个图像的增广视图出发,我们训练在线网络来预测同一图......
  • Efficient and Straggler-Resistant Homomorphic Encryption for Heterogeneous Feder
    为异构联邦学习提供高效且抗掉队者的同态加密技术(INFOCOM24'(CCFA))本文的结构和逻辑清晰,结构设置、文笔以及实验设置和实验分析都值得收藏和反复学习!!!摘要同态加密(HE)被广泛用于加密模型更新,但会产生很高的计算和通信开销。为了减少这些开销,有人提出了打包HE(PHE),将多个明......
  • Advanced .Net Debugging 3:基本调试任务(对象检查:内存、值类型、引用类型、数组和异常
    一、介绍这是我的《Advanced.NetDebugging》这个系列的第四篇文章。今天这篇文章的标题虽然叫做“基本调试任务”,但是这章的内容还是挺多的。由于内容太多,故原书的第三章内容我分两篇文章来写。上一篇我们了解了一些调试技巧,比如:单步调试、下断点、过程调试等,这篇文章主......
  • A. Learning Languages
    https://codeforces.com/problemset/problem/277/AItpresentsaproblemthatweneedtomakeallelementconnected,itcanbesolvedbyusingdsu.Ididn'tusemydsumodelandwriteasimpleversionofDsu.classDSU{public:DSU(intm):size_(m){......
  • Contrastive Learning 对比学习 | 何恺明大神的 SimSiam
    论文题目:ExploringSimpleSiameseRepresentationLearning,CVPR2021。pdf:https://arxiv.org/abs/2011.10566相关博客:知乎|无门槛级讲解对比学习中的自监督模型Simsiam(通俗易懂)知乎|对比学习(ContrastiveLearning):研究进展精要(解释了为什么Simsiam会演变成这样)知......
  • Distance Learning Courses in MAC
    这道题目其实我们如果位运算的题目有取值范围的话(这道题目的\([x,y]\)),我们可以统计公共前缀首先对于一个数对\((x_i,y_i)\)(假设\(x_i≠y_i\)),我们先统计他们的最长公共前缀比如\(000110101\)和\(000111000\),他们的最长公共前缀就是\(000110000\)(位数都是\(32\)位,这里省略了,公共前......
  • CF1935E Distance Learning Courses in MAC
    CF1935EDistanceLearningCoursesinMAC题目大意给定\(n\)个变量\(z_i\in[x_i,y_i]\),你可以在范围内任意指定\(z_i\)的值。\(q\)次查询,每次查询给定区间\([l_i,r_i]\),求用这些变量得到的二进制或最大值。思路选择\(z\in[x,y]\),贡献分为两部分(1)\([x,y]\)的......
  • Advanced .Net Debugging 3:基本调试任务(上)
    一、简介这是我的《Advanced.NetDebugging》这个系列的第三篇文章。这个系列的每篇文章写的周期都要很长,因为每篇文章都是原书的一章内容(太长的就会分开写)。再者说,原书写的有点早,有些内容还是需要修正的,调试每个案例,这都是需要时间的。今天这篇文章的标题虽然叫做“基本......
  • Offline Reinforcement Learning: Tutorial, Review, and Perspectives on Open Probl
    发表时间:2020文章要点:这篇文章主要介绍当前offlineRL的研究进展,可能的问题以及一些解决方法。作者先介绍了强化学习的准备知识,比如policygradients,Approximatedynamicprogramming,Actor-criticalgorithms,Model-basedreinforcementlearning,这里不具体说了。接着开始说offl......
  • 《A Hierarchical Framework for Relation Extraction with Reinforcement Learning》
    代码原文地址摘要现有的大多数方法在确定关系类型之前,需要先识别出所有的实体,这样就忽略了实体提及和关系类型之间的交互。本文提出了一种新颖的联合抽取范式,把相关实体看作是关系的参数(首先检测一个关系,然后提取相应的实体作为关系的参数)。本文在这个范式下采用了一个分层......