您的位置:首页 > 其它

ACM;邮局问题;动态规划;O(n3); 四边形法则可以优化,暂时没研究,等待添加;

2010-04-07 16:22 519 查看
#include <iostream>
using namespace std;

#define MAX 99999

class PostStation
{
private:
int **least;//least[i][j]表示i....n个村庄用j个邮局覆盖的最小距离和
int **cost;//cost[i][j]表示用1个邮局覆盖i....j的最小距离和,邮局位置只有取i到j的中点才会最小,可以证明
int n;//村庄数量
int m;//邮局数量
int *x;//村庄坐标
int **post;//post[i][j]表示i...n个村庄由j个邮局覆盖时的最左邮局

public:

void input()
{
for(int i=1;i<=n;i++)
{
cout<<"第"<<i<<"个村庄的位置:";
cin>>x[i];
}
}

PostStation(int n,int m)
{
this->n=n;
this->m=m;

least=new int* [n+2];//用least[1 to n+1][0 to m]
cost=new int* [n+1];//用cost[1 to n][]
x=new int[n+1];
post=new int* [n+2];

for(int i=0;i<n+1;i++)
{
cost[i]=new int[n+1];
least[i]=new int[m+1];
post[i]=new int[m+1];
}

least[n+1]=new int[m+1];
post[n+1]=new int[m+1];

}

void getCost()
{
int middle;

for(int i=1;i<=n;i++)
{
for(int j=i;j<=n;j++)
{
cost[i][j]=0;
middle=(i+j)/2;

for(int k=i;k<middle;k++)
{
cost[i][j]+=x[middle]-x[k];
}

for(int k=middle+1;k<=j;k++)
{
cost[i][j]+=x[k]-x[middle];
}
}
}
}

void postStation()
{
getCost();
for(int i=1;i<=n+1;i++)
{
for(int j=0;j<=m;j++)
{
least[i][j]=MAX;
}
}

least
[1]=0;
least[n+1][0]=0;

for(int i=n-1;i>=1;i--)
{
for(int j=1;j<=m;j++)
{
for(int k=0;k<=n-i;k++)
{
if(cost[i][i+k]+least[i+k+1][j-1]<least[i][j])
{
least[i][j]=cost[i][i+k]+least[i+k+1][j-1];
post[i][j]=k;
}
}
}
}
cout<<least[1][m]<<endl;
}

};

void main()
{
PostStation test(10,5);
test.input();
test.postStation();
}


 

least[i][m]=min(cost[i][i+k]+least[i+k+1][m-1])     0 <=k <=n-i

 

least
[1]=0  least[n+1][0]=0 

 

least[i][m] 表示从用m个邮局覆盖i......n个村庄

 

用m个邮局覆盖i.....n个村庄的距离和 等于用第一个邮局覆盖 i 到i+k 个村庄的距离和+ 用m-1个邮局覆盖i+k+1......n个村庄的距离和

 

由于用1个邮局覆盖i  到 j 这么多村庄的最小花费一定是将邮局放置在 (i+j)/2 这个村庄的位置, 具体可以证明一下.

 

所以我们用O(n3)时间去计算cost[i][j], 然后用O(n2)时间去计算least[i][m].

 

我们最终想要的是least[i][m],即用m个邮局覆盖i.....n个村庄的最小距离.

 

 

 

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  优化 include input class n2