您的位置:首页 > Web前端

【bzoj4992: [Usaco2017 Feb]Why Did the Cow Cross the Road】动规

2017-12-07 13:11 417 查看

4992: [Usaco2017 Feb]Why Did the Cow Cross the Road

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 190  Solved: 108

[Submit][Status][Discuss]

Description

有一幅n*n的方格图,n <=100,每个点上有一个值。
\从(1,1)出发,走到(n,n),只能走上下左右。
每走一步花费t,每走三步需要花费走完三步后到达格子的值。
求最小花费的值。

Input

Output

Sample Input

4 2

30 92 36 10

38 85 60 16

41 13 5 68

20 97 13 80

Sample Output

31

我们把每一个格子当三个格子来看,来放 步数%3 ,f[x][y][s]可以更新f[x+dx[i]][y+dy[i]][(s+1)%3] , (s==0,1的时候f[x+dx[i]][y+dy[i]][(s+1)%3] =f[x][y][s]+t;s==2的时候f[x+dx[i]][y+dy[i]][(s+1)%3] =f[x][y][s]+t+v[x+dx[i]][y+dy[i]];)

我们把更新掉的状态放到队列里,直到队列为空就结束。

#include<cstdio>
#include<iostream>
#include<queue>
#define ll long long
#define INF (ll)1e16
#define N 105
using namespace std;
int v

,n,t,cnt;
ll f

[3];
queue<int>Q;
struct he{
int x,y,s;
}c[N*N*5];
const int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1};
int main(){
scanf("%d%d",&n,&t);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&v[i][j]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int k=0;k<=2;k++) f[i][j][k]=INF;
f[1][1][0]=0;
cnt++;
c[cnt].x=1;c[cnt].y=1;c[cnt].s=0;
Q.push(cnt);
while(!Q.empty()){
int u=Q.front();Q.pop();
for(int i=0;i<4;i++){
int x1=c[u].x+dx[i],y1=c[u].y+dy[i],s1=(c[u].s+1)%3;
if(1<=x1&&x1<=n&&1<=y1&&y1<=n){
int tmp=0;
if(s1==0) tmp=1;
if(f[c[u].x][c[u].y][c[u].s]+t+tmp*v[x1][y1]<f[x1][y1][s1]){
f[x1][y1][s1]=f[c[u].x][c[u].y][c[u].s]+t+tmp*v[x1][y1];
cnt++;
c[cnt].x=x1;c[cnt].y=y1;c[cnt].s=s1;
Q.push(cnt);
}
}
}
}
printf("%lld",min(f

[0],min(f

[1],f

[2])));
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: