HDOJ 1227 DP

这题参考了别人的思路。

dist是二维数组。dist[i,j]存放“如果i和j两个restaurants之间只有一个depot,则它们之间(包括i和j)的所有restaurants到这个depot的路径之和的最小值”。

ans是二维数组,ans[i,j]存放“为i个restaurants配置j个depots,这i个restaurants到最近的depots的距离之和的最小值”。

则DP转移函数为,ans[i,j]=min{ans[k][j-1]+dist[k+1][i]},j-1<=k<=i-1。也就是说,为前k个restaurants配置j-1个depots,为第k+1~第i个restaurants配置一个depot,选取一个k,使得总距离之和最小。

#include <iostream>
using namespace std;

const int N = 205;
const int K = 35;
int ans[N][K];
int pos[N];
int dist[N][N];/* 若只有一个depot,i,j间的restaurants到这个depot的距离之和的最小值 */

void initDist(int n)
{
    memset(dist,0,sizeof(dist));
    for (int i = 1;i <= n;i ++)
        for (int j = i;j <= n;j ++)
        {
            int mid = (i + j) / 2;
            for (int m = i;m <= j;m ++)
                dist[i][j] += abs(pos[mid] - pos[m]);
        }
}

int main ()
{
    int n,k;
    int caseNum = 1;
    while (scanf("%d%d",&n,&k) != -1)
    {
        if (n == 0 && k == 0)
            break;
        for (int i = 1;i <= n;i ++)
            scanf("%d",&pos[i]);
        initDist(n);
        memset(ans,0,sizeof(ans));
        for (int i = 1;i <= n;i ++)
            ans[i][1] = dist[1][i];
        for (int j = 2;j <= k;j ++)
        {
            for (int i = j;i <= n;i ++)
            {
                int min = -1;
                for (int m = j - 1;m <= i -1;m ++)
                {
                    int temp = ans[m][j - 1] + dist[m + 1][i];
                    if (min == -1)
                        min = temp;
                    else
                        min = min < temp ? min : temp;
                }
                ans[i][j] = min;
            }
        }
        printf("Chain %d\n",caseNum);
        caseNum ++;
        printf("Total distance sum = %d\n\n",ans[n][k]);
    }
    return 0;
}
posted @ 2012-08-13 21:55  peaceful  阅读(148)  评论(0)    收藏  举报