听说你会打地鼠(动态规划dp)
题目来源:https://biancheng.love/contest-ng/index.html#/41/problems
G
听说你会打地鼠
时间限制:300ms 内存限制:65536kb
题目描述
打地鼠是个很简单的游戏,不过你知道怎么打地鼠才能最省力吗?
每时刻,都有N只地鼠在pi(xi,yi)位置出现,打掉一只,该时刻其他地鼠会消失。
打掉第一只地鼠不消耗能量,之后每只地鼠消耗的能量约与鼠标移动距离成正比,即cost = dis(pi,pi+1)(平面上两点距离怎么求不多说了)
现在认为打第一只地鼠不消耗能量,那么打完所有地鼠消耗的最小能量是多少?
输入
多组测试数据
每组测试数据第一行两个整数为时长K和每时刻地鼠数量N
接下来N行每行2N个整数表示N只地鼠坐标
N<=100,K<40
输出
对于每组数据,输出一行,为最小消耗,结果保留3位小数
输入样例
2 2
1 1 3 4
2 2 5 3
输出样例
1.414
解题思路:
状态转移方程:
dp[k][i]=dp[k-1][j]+cost(p[k][i],p[k-1][j]);
说明:dp[k][j] 表示打第k层第j个的时候所能得到的最小值
给出代码:
1 #include <bits/stdc++.h> 2 #define INF 9999999999 3 4 using namespace std; 5 struct Point{ 6 double x; 7 double y; 8 }; 9 10 double cost(Point a,Point b) 11 { 12 return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); 13 } 14 15 Point p[110][110]; 16 double dp[110][110]; 17 int k,n,i,j,f; 18 double ans; 19 int main() 20 { 21 while(~scanf("%d%d",&k,&n)) 22 { 23 ans=INF; 24 for(i=0;i<k;i++)//k层 25 { 26 for(j=0;j<n;j++)//n个 27 { 28 scanf("%lf%lf",&p[i][j].x,&p[i][j].y);//x表示层数,y表示第几个,因此p[x][y]可以确定所选择的地鼠层数以及在该层的位置 29 } 30 } 31 for(f=0;f<k;f++) 32 { 33 for(i=0;i<n;i++) 34 { 35 dp[f][i]=INF; 36 } 37 } 38 // memset(find_min,INF,sizeof(find_min)); 39 for(f=0;f<n;f++) 40 { 41 dp[0][f]=0;//第一只不需要消耗能量 42 } 43 for(f=1;f<k;f++)//第f层 44 { 45 for(i=0;i<n;i++) 46 { 47 for(j=0;j<n;j++) 48 { 49 if(dp[f][i]>(dp[f-1][j]+cost(p[f][i],p[f-1][j])))//状态转移方程 50 dp[f][i]=dp[f-1][j]+cost(p[f][i],p[f-1][j]);//在第f层最小消耗能量等于在第f-1层打第j个地鼠+两点之间距离 51 } 52 } 53 } 54 for(i=0;i<n;i++) 55 { 56 if(ans>dp[k-1][i]) 57 ans=dp[k-1][i]; 58 } 59 printf("%.3lf\n",ans); 60 } 61 }
推荐博客:http://www.tuicool.com/articles/QV7rQjZ
作者: 伊甸一点
出处: http://www.cnblogs.com/zpfbuaa/
本文版权归作者伊甸一点所有,欢迎转载和商用(须保留此段声明),且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
原文链接 如有问题, 可邮件(zpflyfe@163.com)咨询.