• P1282 多米诺骨牌【dp】


    P1282 多米诺骨牌

    提交 20.02k
    通过 6.30k
    时间限制 1.00s
    内存限制 125.00MB
    题目提供者 洛谷
    历史分数100

    提交记录

    标签

     
    查看算法标签
    进入讨论版

    相关讨论

     
    查看讨论

    推荐题目

     
    查看推荐
     

    展开

    题目描述

    多米诺骨牌有上下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

    思路
      把所有点数大的置上,对于反转过的卡牌,重量为-1,价值为 2 * (Y - X),并增加背包原始重量;未反转的,重量为1, 体积为 2 * (X-Y);
      f[i][j] 表示前 i 张牌的体积为 j 的最小重量。
      
    CODE
     1 #include <bits/stdc++.h>
     2 #define dbg(x) cout << #x << "=" << x << endl
     3 #define eps 1e-8
     4 #define pi acos(-1.0)
     5 
     6 using namespace std;
     7 typedef long long LL;
     8 
     9 template<class T>inline void read(T &res)
    10 {
    11     char c;T flag=1;
    12     while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
    13     while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
    14 }
    15 
    16 namespace _buff {
    17     const size_t BUFF = 1 << 19;
    18     char ibuf[BUFF], *ib = ibuf, *ie = ibuf;
    19     char getc() {
    20         if (ib == ie) {
    21             ib = ibuf;
    22             ie = ibuf + fread(ibuf, 1, BUFF, stdin);
    23         }
    24         return ib == ie ? -1 : *ib++;
    25     }
    26 }
    27 
    28 int qread() {
    29     using namespace _buff;
    30     int ret = 0;
    31     bool pos = true;
    32     char c = getc();
    33     for (; (c < '0' || c > '9') && c != '-'; c = getc()) {
    34         assert(~c);
    35     }
    36     if (c == '-') {
    37         pos = false;
    38         c = getc();
    39     }
    40     for (; c >= '0' && c <= '9'; c = getc()) {
    41         ret = (ret << 3) + (ret << 1) + (c ^ 48);
    42     }
    43     return pos ? ret : -ret;
    44 }
    45 
    46 int n;
    47 
    48 int f[1007][6007];
    49 bool vis[1007][6007];
    50 
    51 int w[1007];
    52 int v[1007];
    53 
    54 int main()
    55 {
    56     int x, y;
    57     scanf("%d",&n);
    58     int maxn = 0;
    59     int weight = 0;
    60     for(int i = 1; i <= n; ++i) {
    61         scanf("%d %d",&x, &y);
    62         if(x > y) {
    63             v[i] = 2 * (x-y);
    64             w[i] = 1;
    65             maxn += x-y;
    66         }
    67         if(y > x) {
    68             v[i] = 2 * (y-x);
    69             w[i] = -1;
    70             maxn += y-x;
    71             weight++;
    72         }
    73     }
    74     for(int i = 1; i <= n; ++i) {
    75         for(int j = 1; j <= maxn; ++j) {
    76             f[i][j] = f[i-1][j];
    77             vis[i][j] = vis[i-1][j];
    78             if(vis[i-1][j-v[i]] || !(j - v[i])) {
    79                 if(!vis[i][j]) {
    80                     f[i][j] = f[i-1][j-v[i]] + w[i];
    81                     vis[i][j] = 1;
    82                 }
    83                 else {
    84                     f[i][j] = min(f[i][j], f[i-1][j-v[i]]+w[i]);
    85                 }
    86             }
    87         }
    88     }
    89     int q;
    90     for(int i = maxn; i >= 1; --i) {
    91         if(vis[n][i]) {
    92             q = i;
    93             break;
    94         }
    95     }
    96     printf("%d
    ",weight+f[n][q]);
    97     return 0;
    98 }
    View Code
    
    
    
    
    
  • 相关阅读:
    OAuth2.0系列之授权码模式实践教程(二)
    OAuth2.0系列之基本概念和运作流程(一)
    OAuth2.0系列之单点登录SSO实现
    Mybatis系列之设置自动提交事务
    springMVC系列之@Responsebody接口弹出f.txt下载问题
    Oracle应用之批量递增更新数据脚本
    前端 自定义弹出框-提示框(一)
    IE不兼容问题 字符串格式化
    JS 打开本地应用软件
    PPT导出为图片
  • 原文地址:https://www.cnblogs.com/orangeko/p/12310369.html
Copyright © 2020-2023  润新知