题意:当任意两个卫星的距离小于等于25时,放置一个天线就可以同时接受到这两个卫星的信号。现在告诉n个卫星的位置,求最少需购买天线数量,同时需要保证,得到的信号值总和最大。信号值计算公式是Qx=100-|卫星的位置-天线的位置|。
分析:只要弄清楚了题意,就很容易发现这个题其实就是经典的村庄里建邮局的问题了,只不过这里要求每一段的范围在25以内。因为数据范围只有100,就没写什么优化了,直接上n^3的。 
f[i][j]表示前i个卫星放j个天线所能得到的最大信号。 f[i][j]=max{f[k][j-1]+w[k+1][i]; | d[i]-d[k+1]<=25} 
 #include <iostream>
#include <iostream>
 #include <stdio.h>
#include <stdio.h>
 #include <memory.h>
#include <memory.h>
 #include <algorithm>
#include <algorithm>
 using namespace std;
using namespace std;
 #define eps 1e-8
#define eps 1e-8

 int n;
int n;
 double f[110][110],w[110][110],d[110];
double f[110][110],w[110][110],d[110];

 int main()
int main()


 {
{
 int i,j,k,tem;
    int i,j,k,tem;
 while(scanf("%d",&n)!=EOF)
    while(scanf("%d",&n)!=EOF)

 
     {
{
 d[0]=0.0;
        d[0]=0.0;
 for(i=1;i<=n;i++)
        for(i=1;i<=n;i++) 

 
         {
{
 scanf("%lf",&d[i]);
            scanf("%lf",&d[i]);
 }
        }
 sort(d+1,d+n+1);
        sort(d+1,d+n+1);
 for(i=1;i<=n;i++)   // 预处理出任意一段放一个卫星的所获得的最大信号值。
        for(i=1;i<=n;i++)   // 预处理出任意一段放一个卫星的所获得的最大信号值。

 
         {
{
 w[i][i]=100.0;
            w[i][i]=100.0;
 for(j=i+1;j<=n;j++)
            for(j=i+1;j<=n;j++)

 
             {
{
 tem=i+(j-i+1)/2;
                tem=i+(j-i+1)/2;
 w[i][j]=0.0;
                w[i][j]=0.0;
 for(k=i;k<=tem;k++)
                for(k=i;k<=tem;k++)
 w[i][j]+=d[tem]-d[k];
                    w[i][j]+=d[tem]-d[k];
 for(;k<=j;k++)
                for(;k<=j;k++)
 w[i][j]+=d[k]-d[tem];
                    w[i][j]+=d[k]-d[tem];
 w[i][j]=(j-i+1)*100.0-w[i][j];
                w[i][j]=(j-i+1)*100.0-w[i][j];
 }
            }
 }
        }
 for(i=0;i<=n;i++)
        for(i=0;i<=n;i++)

 
         {
{
 for(j=0;j<=n;j++) f[i][j]=-1.0;
            for(j=0;j<=n;j++) f[i][j]=-1.0;
 }
        }
 f[0][0]=0.0;
        f[0][0]=0.0;
 f[1][1]=100.0;
        f[1][1]=100.0;
 for(i=2;i<=n;i++)
        for(i=2;i<=n;i++)

 
         {
{
 for(j=1;j<=i;j++)
            for(j=1;j<=i;j++)

 
             {
{
 for(k=i-1;k>=j-1&&d[i]+eps<=25.0+d[k+1];k--)
                for(k=i-1;k>=j-1&&d[i]+eps<=25.0+d[k+1];k--)

 
                 {
{
 if(f[k][j-1]+eps<0.0) continue;
                    if(f[k][j-1]+eps<0.0) continue; 
 tem=i-k;
                    tem=i-k;
 if(f[k][j-1]+w[k+1][i]>f[i][j]+eps)
                    if(f[k][j-1]+w[k+1][i]>f[i][j]+eps)
 f[i][j]=f[k][j-1]+w[k+1][i];
                        f[i][j]=f[k][j-1]+w[k+1][i];
 }
                }
 }
            }
 }
        }
 for(j=1;j<=n;j++)
        for(j=1;j<=n;j++)

 
         {
{
 if(f[n][j]>=0) break;
            if(f[n][j]>=0) break;
 }
        }
 printf("%d %.2lf\n",j,f[n][j]);
        printf("%d %.2lf\n",j,f[n][j]);
 }
    }
 return 0;
    return 0;
 }
}