【题目描述】:
xuzhenyi要办个签证。办证处是一座M层的大楼。
每层楼都有N个办公室,编号为1..N。每个办公室有一个签证员。
签证需要让第M层的某个签证员盖章才有效。
每个签证员都要满足下面三个条件之一才会给xuzhenyi盖章:
- 这个签证员在1楼
- xuzhenyi的签证已经给这个签证员的正楼下(房间号相同)的签证员盖过章了。
- xuzhenyi的签证已经给这个签证员的相邻房间(房间号相差1,楼层相同)的签证员盖过章了。
每个签证员盖章都要收取一定费用,这个费用不超过1000000000。
输出最小费用,使签证生效
【输入描述】:
第1行两个整数M和N。
接下来M行每行N个整数,第i行第j个数表示第i层的第j个签证员收取的费用。
【输出描述】:
一个整数,表示最小费用。
【样例输入】:
3 4
10 10 1 10
2 2 2 10
1 10 10 10
【样例输出】:
8
【时间限制、数据范围及描述】:
时间:1s 空间:64M
1<=N<=500; 1<=M<=100
分析:
本题是一道较为简单的DP,用f[i][j]表示到达第i层第j个房间所要的最小花费。另外,本题还需要记住由于本题有后效性故要正反跑两遍DP。
CODE:
1 #include<cstdio> 2 #include<iostream> 3 #define inf 1500000000 4 using namespace std; 5 int s[105][505]; 6 long long f[105][505]; 7 int n,m; 8 int main(){ 9 int i,j,k; 10 long long ans=inf; 11 scanf("%d%d",&n,&m); 12 for(i=1;i<=n;i++) 13 for(j=1;j<=m;j++)f[i][j]=inf; 14 for(i=1;i<=n;i++) 15 for(j=1;j<=m;j++)scanf("%d",&s[i][j]); 16 for(i=1;i<=m;i++)f[1][i]=s[1][i]; 17 for(i=2;i<=n;i++){ 18 for(j=1;j<=m;j++) 19 f[i][j]=min(f[i][j],f[i-1][j]+s[i][j]); 20 for(j=2;j<=m;j++) 21 f[i][j]=min(f[i][j],f[i][j-1]+s[i][j]); 22 for(j=m-1;j>0;j--) 23 f[i][j]=min(f[i][j],f[i][j+1]+s[i][j]); 24 } 25 for(i=1;i<=m;i++) 26 ans=min(ans,f[n][i]); 27 printf("%I64d",ans); 28 }