CodeForces - 1517D Explorer Space(dp)

Posted Frozen_Guardian

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CodeForces - 1517D Explorer Space(dp)相关的知识,希望对你有一定的参考价值。

题目链接:点击查看

题目大意:给出一个 n ∗ m n*m nm 的矩阵,每个点都可以到达相邻的四个点,每条边都有一个边权,问对于每个点 ( 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(nm2k2k2k4),三个 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(nm2k)

最后提一句,第一种方法卡卡常是可以过的,因为看到了前排大佬和我思路一样,但我却给写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 0x0

hge source explor 0x4 input module

hge source explor 0x8 timer

hge source explor 0x5 input module

hge source explor 0xD graphics Ⅳ