标签:pair 位置 cow cpp 距离 需要 poj ace logs
题意:n只牛,第i只牛有Si个合法的坐标(x,y),当n只牛都在它合法的坐标上时,花费为相邻两个点的距离和的累加和(1->2,..n->1).n<=100,si<=40,问最小的花费?
第i只牛,有num[i]种决策
设dp[i][p][j] 前i个人,第1个人在p 最后一个人在j(不连成环)的最小花费
最后ans连成环时需要第一个人的状态.(或者枚举起点)
按照最后一个人已经前一个人的位置转移状态即可 O(100*40*40*40=6e6)
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
typedef pair<double,double> ii;
const int N=2e2+20;
const double inf=2e8;
//题意:n只牛,第i只牛有Si个合法的坐标(x,y),当n只牛都在它合法的坐标上时,
//花费为相邻两个点的距离和的累加和(1->2,..n->1).问最小的花费?
double dp[N][60][60];
int n,num[N];
struct node{
double x,y;
}a[N][N];
double dis(int i,int p,int j,int k)
{
return sqrt((a[i][j].x-a[p][k].x)*(a[i][j].x-a[p][k].x)+(a[i][j].y-a[p][k].y)*(a[i][j].y-a[p][k].y));
}
int main()
{
while(cin>>n)
{
int k;
for(int i=1;i<=n;i++)
{
cin>>num[i];
for(int j=1;j<=num[i];j++)
cin>>a[i][j].x>>a[i][j].y;
}
for(int i=0;i<=n;i++)
for(int j=0;j<=60;j++)
for(int k=0;k<=60;k++)
dp[i][j][k]=inf;
for(int i=1;i<=num[1];i++)
dp[1][i][i]=0;
//第i个人有num[i]种决策
double ans=2e8;
for(int i=2;i<=n;i++)
{
for(int p=1;p<=num[1];p++)
{
for(int j=1;j<=num[i];j++)
{
for(int k=1;k<=num[i-1];k++)//枚举前一个人
{
dp[i][p][j]=min(dp[i][p][j],dp[i-1][p][k]+dis(i,i-1,j,k));
// printf("%lf ",dp[i][p][j]);
}
// printf("\n");
}
}
}
for(int i=1;i<=num[1];i++)
{
for(int j=1;j<=num[n];j++)
{
ans=min(ans,dp[n][i][j]+dis(1,n,i,j));
}
}
ans*=100;
int res=(int)ans;
printf("%d\n",res);
}
return 0;
}
标签:pair 位置 cow cpp 距离 需要 poj ace logs
原文地址:http://www.cnblogs.com/HIKARI1149/p/7000313.html