zoukankan      html  css  js  c++  java
  • 【动态规划】多米诺骨

    贵有恒,何必三更起五更眠;最无益,莫过一日曝十日寒。

     【动态规划】多米诺骨

    时间限制: 1 Sec  内存限制: 128 MB

    题目描述

    多米诺骨牌有上下2个方块组成,每个方块中有1~6个点。现有排成行的n个多米诺骨牌如下图所示。    
    上方块中点数之和记为Σ1 ,下方块中点数之和记为Σ2 ,它们的差为|Σ12| 。例如上图中, Σ1=6+1+1+1=9, Σ2=1+5+3+2=11,|Σ12| =2。每个多米诺骨牌可以旋转180°,使得上下两个方块互换位置。

    编程用最少的旋转次数使多米诺骨牌上下2行点数之差达到最小。

    对于图8-1中的例子,只要将最后一个多米诺骨牌旋转180°,可使上下2行点数之差为0。

    输入

    第一行是一个正整数n(1≤n≤1000),表示多米诺骨牌数。接下来的n行表示n个多米诺骨牌的点数。每行有两个用空格隔开的正整数,表示多米诺骨牌上下方块中的点数a和b,且1≤a,b≤6。

    输出

    仅一行,包含一个整数。表示求得的最小旋转次数。

    样例输入

    4
    6 1
    1 5
    1 3
    1 2
    

    样例输出

    1

    分析:因为存在骨牌上减下为负数的时候,把数组要多开一倍。dp[x]表示和为x的时候最少的交换次数
    dp[j+a]=min(dp[j+a],dp[j]);
    dp[j+b]=min(dp[j+b],dp[j]+1);

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <cstdlib>
    using namespace std;
    const int maxn = 12010;
    
    int dp[maxn], n;
    
    int main()
    {
        int a,b,sum=0,i,j;
        cin>>n;
        for(int i=1;i<maxn;i++)
            dp[i]=200000;
        dp[0]=0;
        for(i=1;i<=n;i++)
        {
            cin>>a>>b;
            sum+=a+b;
            for(j=sum;j>=0;j--)
            {
                int t=dp[j];
                dp[j]=200000;
                dp[j+a]=min(dp[j+a],t);
                dp[j+b]=min(dp[j+b],t+1);
    
            }
        }
        sum=sum/2;
        for(i=sum;i>=0;i--)
            if(dp[i]<=n)
                break;
        for(j=sum;j<maxn;j++)
            if(dp[j]<=n)
                break;
        cout<<min(dp[i],dp[j])<<endl;
        return 0;
    }
    View Code
     
  • 相关阅读:
    欢迎参加MVP主讲的Windows 10开发线上课程
    SharePoint 2013 重复的管理账户错误:已添加项。字典中的关键字 所添加的关键字
    SharePoint 2013 开发——SharePoint Designer 2013工作流
    SharePoint 2013 开发——构建工作流开发环境
    SharePoint 2013 开发——工作流架构
    SharePoint 2013 开发——APP安全模型
    SharePoint 2013 开发——SharePoint APP介绍
    SharePoint 2013 开发——概述
    win32
    hdu2100 26进制加法
  • 原文地址:https://www.cnblogs.com/asuml/p/5740674.html
Copyright © 2011-2022 走看看