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

来源:互联网 发布:wpf和windows什么区别 编辑:程序博客网 时间:2024/05/22 12:00

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 105using namespace std;int v[N][N],n,t,cnt;ll f[N][N][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[n][n][0],min(f[n][n][1],f[n][n][2])));}


阅读全文
0 0
原创粉丝点击