Ural 1167 Bicoloured Horses

动态规划,由于是马进入马厩连续的,要先预处理求出每个连续序列的马进入一个马厩的不快乐值。然后以O(N^2*K)时间复杂度DP。

设A[0][i]为前i匹马中种类为0的马的数量,A[1][i]为前i匹马中种类为1的马的数量。则一个区间[i,j]内的马进入一个马厩的不快乐度U[i,j]为 U[i,j]=( A[0][j] - A[0][i-1] ) * ( A[1][j] - A[1][i-1] )

动态规划状态设定 F[i,j]表示前i个马厩,进入前j匹马的最小不快乐度。

状态转移方程 F[i,j]=min{ F[i-1,k] + U[k+1,j] | k=0..j-1 }

边界条件 F[0,0]=0 F[0,i]=MAX (i=1..N)

目标解 F[K,N]

以下是程序代码

#include <iostream>

using namespace std;

const int MAX=501;
const int INF=0x7FFFFFF;

int N,K;
int Q[MAX],A[2][MAX];
int F[MAX][MAX];

void init()
{
    int i;
    freopen("1167.in","r",stdin);
    freopen("1167.out","w",stdout);
    scanf("%d%d",&N,&K);
    for (i=1;i<=N;i++)
    {
        scanf("%d",&Q[i]);
        A[0][i]=A[0][i-1];
        A[1][i]=A[1][i-1];
        if (Q[i]==0)
            A[0][i]++;
        else
            A[1][i]++;
        F[0][i]=INF;
    }
}

inline int U(int i,int j)
{
    return (A[0][j]-A[0][i-1])*(A[1][j]-A[1][i-1]);
}

void dynamic()
{
    int i,j,k,t,min,u;
    for (i=1;i<=K;i++)
    {
        for (j=1;j<=N;j++)
        {
            min=INF;
            for (k=0;k<=j-1;k++)
            {
                u=U(k+1,j);
                t=F[i-1][k] + u;
                if (t<min)
                    min=t;
            }
            F[i][j]=min;
        }
    }
}

int main()
{
    init();
    dynamic();
    cout << F[K][N] << endl;
    return 0;
}

相关日志