URAL 1167 Bicolored Horses dp练习

Every day, farmer Ion (this is a Romanian name) takes out all his horses, so they may run and play. When they are done, farmer Ion has to take all the horses back to the stables. In order to do this, he places them in a straight line and they follow him to the stables. Because they are very tired, farmer Ion decides that he doesn't want to make the horses move more than they should. So he develops this algorithm: he places the 1st P  1 horses in the first stable, the next P  2 in the 2nd stable and so on. Moreover, he doesn't want any of the  K stables he owns to be empty, and no horse must be left outside. Now you should know that farmer Ion only has black or white horses, which don't really get along too well. If there are  black horses and  j white horses in one stable, then the coefficient of unhappiness of that stable is i*j. The total coefficient of unhappiness is the sum of the coefficients of unhappiness of every of the K stables.

Determine a way to place the N horses into the K stables, so that the total coefficient of unhappiness is minimized.


题目说Ion有n匹马,不是黑就是白,蓝后他有个马厩,每匹马不走回头路的进入马厩,马厩不能有空。

每个马厩里面有何不和谐数,等于黑马数乘白马数

问怎么安排不和谐数之和最小

对于这个问题 窝设了dp[i][j] 表示到第i个马厩放了j匹马的不和谐总数。 蓝后求一下到第 j马,有多少匹白马和黑马

对于dp[i][j] ,  dp[i][j] = min(dp[i-1][k] +(cnt1[j]-cnt1[k])*(cnt0[j]-cnt0[k]),dp[i][j])

就是在前 i - 1个马厩已经放了 k 匹马了 在第i个马厩了里面放了j-k匹马,求这样的最小值

组后输出dp[k][n]就好了

#include 
    
    
     
     
#include 
     
     
      
      
#include 
      
      
       
       
using namespace std;
const int inf = 0x3fffffff;
int dp[510][510];
int cnt1[510],cnt0[511];
int n,k;
int main()
{
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        for(int i = 0; i <= n; i++)
        {
            for(int j = 0; j <= n; j++)
                dp[i][j] = inf;
        }
        for(int i = 0; i <=n; i++){
            dp[i][i] = 0;
            cnt1[i] = cnt0[i] = 0;
        }
        int num;
        for(int i = 1; i <= n; i++)
        {
            scanf("%d",&num);
            cnt1[i] = cnt1[i-1] + num;
            cnt0[i] = cnt0[i-1] +(1-num);
        }
        for(int i = 1; i <= k; i++)
        {
            for(int j = i; j <= n-k+i; j++)
            {
                for(int k = i-1; k < j; k++)
                {
                    dp[i][j] = min(dp[i][j],dp[i-1][k] + (cnt1[j]-cnt1[k])*(cnt0[j]-cnt0[k]));
                }
            }
        }
        printf("%d\n",dp[k][n]);
    }
    return 0;
}

      
      
     
     
    
    

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值