CodeForces - 1517D Explorer Space(dp)
Posted Frozen_Guardian
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CodeForces - 1517D Explorer Space(dp)相关的知识,希望对你有一定的参考价值。
题目链接:点击查看
题目大意:给出一个 n ∗ m n*m n∗m 的矩阵,每个点都可以到达相邻的四个点,每条边都有一个边权,问对于每个点 ( i , j ) (i,j) (i,j),走 k k k 步可以回到 ( i , j ) (i,j) (i,j) 的最短路径
题目分析:首先不难看出 k k k 如果是奇数的话无解,然后可以将题目转换为:从 ( i , j ) (i,j) (i,j) 走 k 2 \\frac{k}{2} 2k 步可以到达的最短路径,不难看出用后 k 2 \\frac{k}{2} 2k 步沿着前面的路径原路返回这样一定是最优的
第一反应是暴力每个点,就是对于每个点 ( x , y ) (x,y) (x,y) 来说单独思考, d p i , j , k dp_{i,j,k} dpi,j,k 代表从点 ( x , y ) (x,y) (x,y) 出发走了 k k k 步到达点 ( i , j ) (i,j) (i,j) 的最短路径,这样思考正确性毋庸置疑,就是时间复杂度有点大: O ( n ∗ m ∗ k 2 ∗ k 2 ∗ k 2 ∗ 4 ) O(n*m*\\frac{k}{2}*\\frac{k}{2}*\\frac{k}{2}*4) O(n∗m∗2k∗2k∗2k∗4),三个 k 2 \\frac{k}{2} 2k 分别代表需要转移的矩形的长和宽,以及需要迭代的次数, 4 4 4 代表的是每次需要向四个方向转移
后来发现,我们并不需要关注起点在哪,只需要关注走了 k 2 \\frac{k}{2} 2k 步之后到达 ( x , y ) (x,y) (x,y) 的最小路径是多少就行,直接乘以 2 2 2 就是我们需要的答案了
所以直接迭代 k 2 \\frac{k}{2} 2k 次,更新每个点的状态即可,时间复杂度 O ( n ∗ m ∗ k 2 ) O(n*m*\\frac{k}{2}) O(n∗m∗2k)
最后提一句,第一种方法卡卡常是可以过的,因为看到了前排大佬和我思路一样,但我却给写T了,代码放在后面,主要是展示思路
代码:
AC代码
// #pragma GCC optimize(2)
// #pragma GCC optimize("Ofast","inline","-ffast-math")
// #pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
#include<list>
#include<unordered_map>
#define lowbit(x) x&-x
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
template<typename T>
inline void read(T &x)
{
T f=1;x=0;
char ch=getchar();
while(0==isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(0!=isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
x*=f;
}
template<typename T>
inline void write(T x)
{
if(x<0){x=~(x-1);putchar('-');}
if(x>9)write(x/10);
putchar(x%10+'0');
}
const int inf=0x3f3f3f3f;
const int N=510;
const int b[4][2]={0,1,0,-1,1,0,-1,0};
int n,m,k;
int raw[N][N],col[N][N];//raw[i][j]:(i,j)->(i,j+1) col[i][j]:(i,j)->(i+1,j)
int dp[N][N][11];
int main()
{
#ifndef ONLINE_JUDGE
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
#endif
// ios::sync_with_stdio(false);
read(n),read(m),read(k);
for(int i=1;i<=n;i++) {
for(int j=1;j<m;j++) {
read(raw[i][j]);
}
}
for(int i=1;i<n;i++) {
for(int j=1;j<=m;j++) {
read(col[i][j]);
}
}
if(k&1) {
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) {
printf("-1 ");
}
puts("");
}
return 0;
}
k/=2;
for(int t=1;t<=k;t++) {
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) {
dp[i][j][t]=inf;
for(int p=0;p<4;p++) {
int xx=i+b[p][0];
int yy=j+b[p][1];
if(xx<=0||xx>n||yy<=0||yy>m) {
continue;
}
int w;
if(p==0) {
w=raw[i][j];
} else if(p==1) {
w=raw[xx][yy];
} else if(p==2) {
w=col[i][j];
} else if(p==3) {
w=col[xx][yy];
}
dp[i][j][t]=min(dp[i][j][t],dp[xx][yy][t-1]+w*2);
}
}
}
}
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) {
printf("%d ",dp[i][j][k]);
}
puts("");
}
return 0;
}
TLE代码:
// #pragma GCC optimize(2)
// #pragma GCC optimize("Ofast","inline","-ffast-math")
// #pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
#include<list>
#include<unordered_map>
#define lowbit(x) x&-x
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
template<typename T>
inline void read(T &x)
{
T f=1;x=0;
char ch=getchar();
while(0==isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(0!=isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
x*=f;
}
template<typename T>
inline void write(T x)
{
if(x<0){x=~(x-1);putchar('-');}
if(x>9)write(x/10);
putchar(x%10+'0');
}
const int inf=0x3f3f3f3f;
const int N=510;
const int b[4][2]={0,1,0,-1,1,0,-1,0};
int n,m,k;
int raw[N][N],col[N][N];//raw[i][j]:(i,j)->(i,j+1) col[i][j]:(i,j)->(i+1,j)
int dp[N][N][11];
struct Node {
int x,y,step;
};
int solve(int x,int y,int k) {
for(int t=0;t<=k;t++) {
for(int i=max(x-t,1);i<=min(x+t,n);i++) {
int d=t-abs(i-x);
for(int j=max(y-d,1);j<=minhge source explor 0x6 input module
hge source explor 0x4 input module