atcoder AtCoder Beginner Contest 210 D - National Railway(dp)
传送门
思路:
首先考虑暴力的做法,枚举两个点计算距离后取最小值,复杂度 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)相关推荐
- zzuli 2177 Contest - 河南省多校连萌(四)(简单题)
Contest - 河南省多校连萌(四) Problem F: 小姐姐的忠告:少吃辣条多刷题 题目链接 Time Limit: 1 Sec Memory Limit: 128 MB Submit: 1 ...
- 20201016:力扣第210周周赛题解(下)
力扣第210周周赛题解(下) 题目 思路与算法 代码实现 写在最后 题目 分割两个字符串得到回文串 统计子树中城市之间最大距离 思路与算法 第三题主要逻辑通顺就行,注意分割的索引是一样的,那么判断回文 ...
- AtCoder题解——Beginner Contest 170——E - Smart Infants
题目相关 题目链接 AtCoder Beginner Contest 170 E 题,https://atcoder.jp/contests/abc170/tasks/abc170_e. Proble ...
- AtCoder题解——Beginner Contest 179——D - Leaping Tak
题目相关 题目链接 AtCoder Beginner Contest 179 D 题,https://atcoder.jp/contests/abc179/tasks/abc179_d. Proble ...
- AtCoder题解——Beginner Contest 170——F - Pond Skater
题目相关 题目链接 AtCoder Beginner Contest 170 F题,https://atcoder.jp/contests/abc170/tasks/abc170_f. Problem ...
- AtCoder题解——Beginner Contest 167——C - Skill Up
题目相关 题目链接 AtCoder Beginner Contest 167 C题,https://atcoder.jp/contests/abc167/tasks/abc167_c. Problem ...
- AtCoder Beginner Contest 211 E - Red Polyomino(暴力+状态记录)
E - Red Polyomino 暴力,对于状态的记录考虑下面用set<vector<string>> mp #include<bits/stdc++.h> us ...
- AtCoder Beginner Contest 205D题Kth Excluded(差分+二分)
题目链接 给出N个数和Q组询问,每次询问输出第K小的数,并且该数不能是N个数中的 考虑先做差分 pre[i] 表示每个数之间可以插入多少个数 然后将差分做个前缀和,sum[i]=k 表示前i个数可以放 ...
- AtCoder Beginner Contest 217 D - Cutting Woods(set + 二分查找)
题目大意 有一根长度为L的木头,这根木头上有L - 1个可以劈的点,对这根木头进行q次操作,操作有两种:操作一是往一个可劈点劈一刀,把这个点所在的木头段劈成两段:操作二是输出一个可劈点所在木头段的长度 ...
最新文章
- 入门指南目录页 -PaddlePaddle 飞桨 入门指南 FAQ合集-深度学习问题
- jQuery 在Table中选择input之类的东西注意事项
- python2基础教程廖雪峰云-Python 基础教程
- hdu 2191 多重背包
- vue常见知识点整理
- 三、HDFS中的Java和Python API接口连接
- P4231 三步必杀 二次差分
- matlab 限幅,限幅是什么意思
- Leetcode每日一题:1002.find-common-characters(查找常用字符串)
- 在生意不好做的情况下, 你会选择坚持,还是去重新找一个新行业?
- weblogic的安装、目录结构、启动
- Visio 2013 破解工具 - KMSpico(亲测可用)
- drupal主题开发_开发人员充满了Drupal的活力和活力
- 分享一个空手反套白狼的骚操作
- 智云通CRM:大客户销售流程,新手也能快速入门
- 小故事大道理--驴子的逃离
- 验证输入是否为正确的组织机构代码
- 计算机多媒体课件设计,多媒体课件设计与制作 教师课件制作平台
- rdd数据存内存 数据量_超全spark性能优化总结
- 影像分辨率、地面分辨率、比例尺及DPI之间的关系
热门文章
- 设置ZIP文件打开密码的两种方法
- spring:Failed to convert property value of type ‘java.lang.String‘ to required type ‘java.util.Date‘
- 微信小程序中引用FontAwesome字体 最完整教程 附下载源码
- 量子计算机与易经,易经卦象的演化过程,就是一个量子计算机模型
- 列举网络爬虫所用到的网络数据包,解析包?
- Android 合并清单文件 Merge multiple manifest files
- 微信公众号跳转小程序流程简单梳理(未完待续)
- 并发包大神Doug Lea
- 一文说清“链上”和“链下”
- 如何把位图转成矢量图