链接:点击打开链接
这道题一开始看的时候,觉得就是一个DP,不过刚开始想的是用一维数组dp[550],但是出现一个问题,就是第一次打地鼠时不消耗任何能量,因为是求最少消耗的能量,所以第一次打地鼠的位置我肯定标记为零,但是我后面从另外一个位置又打到这个位置时,这个位置已经标记为零了,所以最小为零,所以前面的能量就消失啦。
这组数据,第一次dp[3]=0,状态转移方程dp[a[i][j]]=min(dp[a[i][j]],dp[a[i-1][x]]+abs(a[i-1][x]-a[i][j]));本来dp[3]应该等于1,但就是因为取最小,而第一次打dp[3]=0,所以没有更新,所以用一维错啦。
后面果断用二维数组dp[25][500],表示打了前i个地鼠在j位置消耗了多少能量,状态转移方程dp[i][a[i][j]]=min(dp[i][a[i][j]],dp[i-1][a[i-1][x]]+abs(a[i-1][x]-a[i][j]));
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
#define INF 1000000
int min(int x,int y){
if(x<y)
return x;
else
return y;
}
int main(){
int i,j,n,k,dp[25][550],a[25][15],m,x;
while(~scanf("%d %d",&n,&k)){
for(i=1;i<25;i++)
for(j=1;j<=550;j++)
dp[i][j]=INF;
for(i=1;i<=n;i++)
for(j=1;j<=k;j++)
scanf("%d",&a[i][j]);
for(i=1;i<=k;i++)
dp[1][a[1][i]]=0;
for(i=2;i<=n;i++)
for(j=1;j<=k;j++)
for(x=1;x<=k;x++){
dp[i][a[i][j]]=min(dp[i][a[i][j]],dp[i-1][a[i-1][x]]+abs(a[i-1][x]-a[i][j]));
}
m=INF;
for(j=1;j<=500;j++)
if(m>dp[n][j])
m=dp[n][j];
printf("%d\n",m);
}
return 0;
}
暴力解法:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
int min(int x,int y){
if(x<y)
return x;
else
return y;
}
#define INF 1000000
int main(){
int i,j,n,k,x,a[25][15],b[25][15],anx;
while(~scanf("%d %d",&n,&k)){
for(i=1;i<25;i++)
for(j=1;j<15;j++)
b[i][j]=INF;
for(i=1;i<=n;i++)
for(j=1;j<=k;j++)
scanf("%d",&a[i][j]);
for(i=1;i<=k;i++)
b[1][i]=0;
for(i=2;i<=n;i++)
for(j=1;j<=k;j++)
for(x=1;x<=k;x++)
b[i][j]=min(b[i][j],b[i-1][x]+abs(a[i-1][x]-a[i][j]));
anx=INF;
for(i=1;i<=k;i++)
if(anx>b[n][i])
anx=b[n][i];
printf("%d\n",anx);
}
return 0;
}