zoukankan      html  css  js  c++  java
  • 多米诺骨牌

    题目描述

    多米诺骨牌有上下2个方块组成,每个方块中有1~6个点。现有排成行的

    上方块中点数之和记为S1,下方块中点数之和记为S2,它们的差为|S1-S2|。例如在图8-1中,S1=6+1+1+1=9,S2=1+5+3+2=11,|S1-S2|=2。每个多米诺骨牌可以旋转180°,使得上下两个方块互换位置。 编程用最少的旋转次数使多米诺骨牌上下2行点数之差达到最小。

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

    输入输出格式

    输入格式:

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

    输出格式:

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

    输入输出样例

    输入样例#1: 
    4
    6 1
    1 5
    1 3
    1 2
    
    输出样例#1: 
    1

    分析:
    本题是一道较难的DP题,但是可以通过对多米诺骨牌进行翻转从而实现将本题变为一道较为容易的背包DP,即用f[i][j]表示前i件物品能装到体积为j的最小重量

    CODE(诡异的码风???显然不是我写的吗。。。):
     1 #include<cstdio>
     2 #include<iostream>
     3 #include<string>
     4 #include<cstring>
     5 #include<cmath>
     6 #define rep(o,t,k) for(int o=t;o<=k;o++)
     7 using namespace std;
     8 int i,j,k;
     9 int l,m,n,up,sum,inf,down,u[1200],d[1200],f[1200][20000];
    10 int main(){
    11     scanf("%d",&n);
    12     rep(i,1,n) {
    13         scanf("%d%d",&u[i],&d[i]);
    14         up+=u[i];down+=d[i];sum+=u[i]+d[i];
    15     }
    16     memset(f,62,sizeof(f));inf=f[0][0];
    17     f[0][up]=0;
    18     rep(i,1,n)
    19       rep(j,1,sum){
    20            if(j-u[i]+d[i]<0) continue;
    21            f[i][j]=min(f[i-1][j],f[i-1][j+u[i]-d[i]]+1);
    22       }
    23     int p=99999,step;
    24     for(int i=sum;i>=0;i--){
    25         if(abs(sum-i-i)<p&&f[n][i]<inf){
    26             p=abs(sum-i-i);
    27             step=f[n][i];
    28         }
    29     }
    30     printf("%d",step);
    31     return 0;
    32 }


  • 相关阅读:
    如何生成不规则形状的mask,以解决对图像不规则区域设置ROI的问题
    数字图像处理学习1
    opencv显示图像
    Calling Matlab Neural Network From Other EXE's
    这个百度文档很给力
    opencv不规则ROI——圆形ROI
    问题修改
    skinsmagic美化MFC界面
    第一次使用思维导图
    libsvm使用介绍中文版
  • 原文地址:https://www.cnblogs.com/kanchuang/p/11188251.html
Copyright © 2011-2022 走看看