POJ 2137 Cowties 线性DP
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 2137 Cowties 线性DP相关的知识,希望对你有一定的参考价值。
题意: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; }
以上是关于POJ 2137 Cowties 线性DP的主要内容,如果未能解决你的问题,请参考以下文章