题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4362
设dp[i][j]表示第i批龙珠中取第j个需要花费的最小体力。
dp[i][j] = min{ dp[i-1][k] + abs(pos[i-1][k]-pos[i][j]) } + cost[i][j];
官方题解说这样会超时,但是是可以蹭过去的。。
1 #include <iostream>
2 #include <cstring>
3 #include <cstdio>
4 const int N=51;
5 const int M=1001;
6 const int inf=0x7fffffff;
7 int pos[N][M],cost[N][M],dp[N][M];
8 int main()
9 {
10 int t,n,m,i,j,k,x,min,ab;
11 scanf("%d",&t);
12 while(t--)
13 {
14 scanf("%d%d%d",&n,&m,&x);
15 for(i=1;i<=n;i++)
16 for(j=1;j<=m;j++)
17 scanf("%d",&pos[i][j]);
18 for(i=1;i<=n;i++)
19 for(j=1;j<=m;j++)
20 scanf("%d",&cost[i][j]);
21 for(i=1;i<=m;i++)
22 {
23 ab=x-pos[1][i];
24 if(ab<0)
25 ab=-ab;
26 dp[1][i]=ab+cost[1][i];
27 }
28 for(i=2;i<=n;i++)
29 {
30 for(j=1;j<=m;j++)
31 {
32 min=inf;
33 for(k=1;k<=m;k++)
34 {
35 ab=pos[i][j]-pos[i-1][k];
36 if(ab<0)
37 ab=-ab;
38 if(min>dp[i-1][k]+ab+cost[i][j])
39 min=dp[i-1][k]+ab+cost[i][j];
40 }
41 dp[i][j]=min;
42 }
43 }
44 min=inf;
45 for(i=1;i<=m;i++)
46 {
47 if(min>dp[n][i])
48 min=dp[n][i];
49 }
50 printf("%d\n",min);
51 }
52 return 0;
53 }
2 #include <cstring>
3 #include <cstdio>
4 const int N=51;
5 const int M=1001;
6 const int inf=0x7fffffff;
7 int pos[N][M],cost[N][M],dp[N][M];
8 int main()
9 {
10 int t,n,m,i,j,k,x,min,ab;
11 scanf("%d",&t);
12 while(t--)
13 {
14 scanf("%d%d%d",&n,&m,&x);
15 for(i=1;i<=n;i++)
16 for(j=1;j<=m;j++)
17 scanf("%d",&pos[i][j]);
18 for(i=1;i<=n;i++)
19 for(j=1;j<=m;j++)
20 scanf("%d",&cost[i][j]);
21 for(i=1;i<=m;i++)
22 {
23 ab=x-pos[1][i];
24 if(ab<0)
25 ab=-ab;
26 dp[1][i]=ab+cost[1][i];
27 }
28 for(i=2;i<=n;i++)
29 {
30 for(j=1;j<=m;j++)
31 {
32 min=inf;
33 for(k=1;k<=m;k++)
34 {
35 ab=pos[i][j]-pos[i-1][k];
36 if(ab<0)
37 ab=-ab;
38 if(min>dp[i-1][k]+ab+cost[i][j])
39 min=dp[i-1][k]+ab+cost[i][j];
40 }
41 dp[i][j]=min;
42 }
43 }
44 min=inf;
45 for(i=1;i<=m;i++)
46 {
47 if(min>dp[n][i])
48 min=dp[n][i];
49 }
50 printf("%d\n",min);
51 }
52 return 0;
53 }