传送门

思路:

首先考虑暴力的做法,枚举两个点计算距离后取最小值,复杂度 O ( n 4 ) O(n^{4}) O(n4)
考虑怎么优化。
首先可以确定的是,一定要枚举一个点,那么可以通过控制坐标的大小关系将绝对值去掉。
假设对于点 ( i , j ) (i,j) (i,j),只考虑点 ( x , y ) (x,y) (x,y)满足 i < = x < = n , j < = y < = m i<=x<=n,j<=y<=m i<=x<=n,j<=y<=m
那么代价就变成了 a [ i ] [ j ] + a [ x ] [ y ] + c ∗ ( x − i ) + c ∗ ( y − j ) a[i][j]+a[x][y]+c*(x-i)+c*(y-j) a[i][j]+a[x][y]+c∗(x−i)+c∗(y−j)
拆开得到 a [ i ] [ j ] − c ∗ i − c ∗ j + a [ x ] [ y ] + c ∗ x + c ∗ y a[i][j]-c*i-c*j+a[x][y]+c*x+c*y a[i][j]−c∗i−c∗j+a[x][y]+c∗x+c∗y
对于点 ( i , j ) (i,j) (i,j)的贡献 a [ i ] [ j ] − c ∗ i − c ∗ j a[i][j]-c*i-c*j a[i][j]−c∗i−c∗j,可以通过枚举计算;
对于点 ( x , y ) (x,y) (x,y)的贡献 a [ x ] [ y ] + c ∗ x + c ∗ y a[x][y]+c*x+c*y a[x][y]+c∗x+c∗y,由于题目要求代价最小,所以应当维护最小值。
也就是说 d p [ i ] [ j ] dp[i][j] dp[i][j]表示的是对于满足 i < = x < = n , j < = y < = m i<=x<=n,j<=y<=m i<=x<=n,j<=y<=m的所有的点 ( x , y ) (x,y) (x,y)的贡献 a [ x ] [ y ] + c ∗ x + c ∗ y a[x][y]+c*x+c*y a[x][y]+c∗x+c∗y的最小值。
所以每次枚举到 ( i , j ) (i,j) (i,j)时,只需要假定这个点必选,再加上 d p [ i ] [ j ] dp[i][j] dp[i][j]表示上一个点的贡献,所有的答案取最小值即可,注意更新完答案后应当更新 d p dp dp数组。
这样会产生的一个问题就是,只是考虑了两个点的位置大致是呈左上-右下的趋势的情况,如果一个点在右上,另一个点在左下,这种情况没有被枚举到。
所以还应该再跑一遍,基本流程同上文类似。

代码:

又臭又长的垃圾代码:(下一个是比较简洁的代码!)


ll n,m,c,a[1100][1100],dp[1100][1100],dp1[1100][1100];int main(){n=read,m=read,c=read;rep(i,1,n) rep(j,1,m) a[i][j]=read;rep(i,0,n+1) rep(j,0,m+1) dp[i][j]=1e18,dp1[i][j]=1e18;ll res=1e18;for(int i=n;i;i--)for(int j=m;j;j--){ll now=a[i][j]-c*i-c*j;ll las=1e18;if(i+1<=n&&j+1<=m) las=min(las,dp[i+1][j+1]);if(i+1<=n) las=min(las,dp[i+1][j]);if(j+1<=m) las=min(las,dp[i][j+1]);res=min(res,now+las);dp[i][j]=min(dp[i][j],a[i][j]+c*i+c*j);if(i+1<=n&&j+1<=m) dp[i][j]=min(dp[i][j],dp[i+1][j+1]);if(i+1<=n) dp[i][j]=min(dp[i][j],dp[i+1][j]);if(j+1<=m) dp[i][j]=min(dp[i][j],dp[i][j+1]);}for(int i=1;i<=n;i++){for(int j=m;j;j--){ll now=a[i][j]+c*i-c*j;ll las=1e18;if(i-1>=1&&j+1<=m) las=min(las,dp1[i-1][j+1]);if(i-1>=1) las=min(las,dp1[i-1][j]);if(j+1<=m) las=min(las,dp1[i][j+1]);res=min(res,now+las);dp1[i][j]=min(dp1[i][j],a[i][j]-c*i+c*j);if(i-1>=1&&j+1<=m) dp1[i][j]=min(dp1[i][j],dp1[i-1][j+1]);if(i-1>=1) dp1[i][j]=min(dp1[i][j],dp1[i-1][j]);if(j+1<=m) dp1[i][j]=min(dp1[i][j],dp1[i][j+1]);}}printf("%lld\n",res);return 0;
}

跟我的思路类似但是代码超级简洁的巨巨代码:

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <cstdio>
#define endl '\n'
#define int long long
#define pb push_back
#define mp make_pair
#define INF 0x3f3f3f3f
#define Inf 1000000000000000000LL
#define F first
#define S second
using namespace std;
typedef pair<int,int>pii;
int n,m,C;
int a[1010][1010];
int dp[1010][1010];
int ans=0x3f3f3f3f3f3f3f3f;
void DP(){memset(dp,0x3f,sizeof dp);for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){dp[i][j]=min(dp[i][j-1],dp[i-1][j]);ans=min(ans,dp[i][j]+a[i][j]+C*(i+j));dp[i][j]=min(dp[i][j],a[i][j]-C*(i+j));}}
}
signed main(){cin>>n>>m>>C;for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)cin>>a[i][j];DP();for(int i=1;i<=n;i++){int l=1,r=m;while(l<r){swap(a[i][l],a[i][r]);l++,r--;}}DP();cout<<ans<<endl;return 0;
}

赛时写假了边界,宇巨一波奇技淫巧强行AC的代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll>PLL;
typedef pair<int, int>PII;
typedef pair<double, double>PDD;
#define I_int ll
inline ll read()
{ll x = 0, f = 1;char ch = getchar();while(ch < '0' || ch > '9'){if(ch == '-')f = -1;ch = getchar();}while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}return x * f;
}inline void out(ll x){if (x < 0) x = ~x + 1, putchar('-');if (x > 9) out(x / 10);putchar(x % 10 + '0');
}inline void write(ll x){if (x < 0) x = ~x + 1, putchar('-');if (x > 9) write(x / 10);putchar(x % 10 + '0');puts("");
}#define read read()
#define closeSync ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define multiCase int T;cin>>T;for(int t=1;t<=T;t++)
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i<(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define perr(i,a,b) for(int i=(a);i>(b);i--)
ll ksm(ll a, ll b, ll p)
{ll res = 1;while(b){if(b & 1)res = res * a % p;a = a * a % p;b >>= 1;}return res;
}
const int inf = 0x3f3f3f3f;
#define PI acos(-1)
const int maxn=4e5+100;ll n,m,c,a[1100][1100],dp[1100][1100],dp1[1100][1100];
struct Node{ll x,y,val;
}t[1000009];
bool cmp(Node x,Node y)
{return x.val<y.val;
}
int main(){n=read,m=read,c=read;ll cnt=0;rep(i,1,n) rep(j,1,m) {a[i][j]=read,dp[i][j]=1e18,dp1[i][j]=1e18;t[++cnt] = {i,j,a[i][j]};}if(n*m<=30000){ll anss = 1e18;sort(t+1,t+1+cnt,cmp);rep(i,1,min(n*m,30000ll))     rep(j,1,min(n*m,30000ll)){if(i==j) continue;ll x1,y1,x2,y2,val1,val2;x1 = t[i].x,y1 = t[i].y,val1 = t[i].val;x2 = t[j].x,y2 = t[j].y,val2 = t[j].val;ll temp = c*(abs(x1-x2)+abs(y1-y2)) +val1+val2;anss = min(anss,temp);}printf("%lld",anss);return 0;}ll res=1e18;for(int i=n;i;i--)for(int j=m;j;j--){if(i==n&&j==m){dp[i][j]=a[i][j]+c*i+c*j;continue;}ll now=a[i][j]-c*i-c*j;ll las=1e18;if(i+1<=n&&j+1<=m) las=min(las,dp[i+1][j+1]);if(i+1<=n) las=min(las,dp[i+1][j]);if(j+1<=m) las=min(las,dp[i][j+1]);res=min(res,now+las);dp[i][j]=min(dp[i][j],a[i][j]+c*i+c*j);if(i+1<=n&&j+1<=m) dp[i][j]=min(dp[i][j],dp[i+1][j+1]);if(i+1<=n) dp[i][j]=min(dp[i][j],dp[i+1][j]);if(j+1<=m) dp[i][j]=min(dp[i][j],dp[i][j+1]);}for(int i=1;i<=n;i++){for(int j=m;j;j--){if(i==1&&j==m){dp1[i][j]=a[i][j]+c*i+c*j;continue;}ll now=a[i][j]+c*i-c*j;ll las=1e18;if(i-1>=1&&j+1<=m) las=min(las,dp1[i-1][j+1]);if(i-1>=1) las=min(las,dp1[i-1][j]);if(j+1<=m) las=min(las,dp1[i][j+1]);res=min(res,now+las);dp1[i][j]=min(dp1[i][j],a[i][j]-c*i+c*j);if(i-1>=1&&j+1<=m) dp1[i][j]=min(dp1[i][j],dp1[i-1][j+1]);if(i-1>=1) dp1[i][j]=min(dp1[i][j],dp1[i-1][j]);if(j+1<=m) dp1[i][j]=min(dp1[i][j],dp1[i][j+1]);}}printf("%lld\n",res);return 0;
}
/*
-4999000000****1061109567****3****2
-4999000000****1061109567****2****3
-3937890433
2001000000 3001000000 4000000001
3001000000 4001000000 5001000000
4000000001 5001000000 6001000000 */

atcoder AtCoder Beginner Contest 210 D - National Railway(dp)相关推荐

  1. zzuli 2177 Contest - 河南省多校连萌(四)(简单题)

    Contest - 河南省多校连萌(四) Problem F: 小姐姐的忠告:少吃辣条多刷题 题目链接 Time Limit: 1 Sec Memory Limit: 128 MB Submit: 1 ...

  2. 20201016:力扣第210周周赛题解(下)

    力扣第210周周赛题解(下) 题目 思路与算法 代码实现 写在最后 题目 分割两个字符串得到回文串 统计子树中城市之间最大距离 思路与算法 第三题主要逻辑通顺就行,注意分割的索引是一样的,那么判断回文 ...

  3. AtCoder题解——Beginner Contest 170——E - Smart Infants

    题目相关 题目链接 AtCoder Beginner Contest 170 E 题,https://atcoder.jp/contests/abc170/tasks/abc170_e. Proble ...

  4. AtCoder题解——Beginner Contest 179——D - Leaping Tak

    题目相关 题目链接 AtCoder Beginner Contest 179 D 题,https://atcoder.jp/contests/abc179/tasks/abc179_d. Proble ...

  5. AtCoder题解——Beginner Contest 170——F - Pond Skater

    题目相关 题目链接 AtCoder Beginner Contest 170 F题,https://atcoder.jp/contests/abc170/tasks/abc170_f. Problem ...

  6. AtCoder题解——Beginner Contest 167——C - Skill Up

    题目相关 题目链接 AtCoder Beginner Contest 167 C题,https://atcoder.jp/contests/abc167/tasks/abc167_c. Problem ...

  7. AtCoder Beginner Contest 211 E - Red Polyomino(暴力+状态记录)

    E - Red Polyomino 暴力,对于状态的记录考虑下面用set<vector<string>> mp #include<bits/stdc++.h> us ...

  8. AtCoder Beginner Contest 205D题Kth Excluded(差分+二分)

    题目链接 给出N个数和Q组询问,每次询问输出第K小的数,并且该数不能是N个数中的 考虑先做差分 pre[i] 表示每个数之间可以插入多少个数 然后将差分做个前缀和,sum[i]=k 表示前i个数可以放 ...

  9. AtCoder Beginner Contest 217 D - Cutting Woods(set + 二分查找)

    题目大意 有一根长度为L的木头,这根木头上有L - 1个可以劈的点,对这根木头进行q次操作,操作有两种:操作一是往一个可劈点劈一刀,把这个点所在的木头段劈成两段:操作二是输出一个可劈点所在木头段的长度 ...

最新文章

  1. 入门指南目录页 -PaddlePaddle 飞桨 入门指南 FAQ合集-深度学习问题
  2. jQuery 在Table中选择input之类的东西注意事项
  3. python2基础教程廖雪峰云-Python 基础教程
  4. hdu 2191 多重背包
  5. vue常见知识点整理
  6. 三、HDFS中的Java和Python API接口连接
  7. P4231 三步必杀 二次差分
  8. matlab 限幅,限幅是什么意思
  9. Leetcode每日一题:1002.find-common-characters(查找常用字符串)
  10. 在生意不好做的情况下, 你会选择坚持,还是去重新找一个新行业?
  11. weblogic的安装、目录结构、启动
  12. Visio 2013 破解工具 - KMSpico(亲测可用)
  13. drupal主题开发_开发人员充满了Drupal的活力和活力
  14. 分享一个空手反套白狼的骚操作
  15. 智云通CRM:大客户销售流程,新手也能快速入门
  16. 小故事大道理--驴子的逃离
  17. 验证输入是否为正确的组织机构代码
  18. 计算机多媒体课件设计,多媒体课件设计与制作 教师课件制作平台
  19. rdd数据存内存 数据量_超全spark性能优化总结
  20. 影像分辨率、地面分辨率、比例尺及DPI之间的关系

热门文章

  1. 设置ZIP文件打开密码的两种方法
  2. spring:Failed to convert property value of type ‘java.lang.String‘ to required type ‘java.util.Date‘
  3. 微信小程序中引用FontAwesome字体 最完整教程 附下载源码
  4. 量子计算机与易经,易经卦象的演化过程,就是一个量子计算机模型
  5. 列举网络爬虫所用到的网络数据包,解析包?
  6. Android 合并清单文件 Merge multiple manifest files
  7. 微信公众号跳转小程序流程简单梳理(未完待续)
  8. 并发包大神Doug Lea
  9. 一文说清“链上”和“链下”
  10. 如何把位图转成矢量图