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

    中文题

    想法:

    观察到每次交换只是把上下两个数交换,故前i个骨牌上下两行数的总和是不变的,所以我们只需记录其中一行数字的和就可以知道差值了。这样状态就好表示了。

    f[i][j]表示前i个数字,第一行的数字和是j时,最小的交换次数。初始值所有f[i][j]都是无穷大,f[1][a[1]]=0,f[1][b[1]]=1。(a[]和b[]分别表示第一行和第二行的数字)

    转移时,枚举每一个可能的和,共有6*n个,考虑当前一个交不交换即可

     

    最后去枚举第一行的和去找满足题意(差值最小)的最小交换次数

    #include <algorithm>
    #include <string>
    #include <string.h>
    #include <vector>
    #include <map>
    #include <stack>
    #include <set>
    #include <queue>
    #include <math.h>
    #include <cstdio>
    #include <iomanip>
    #include <time.h>
    #include <bitset>
    #include <cmath>
    #include <sstream>
    #include <iostream>
    #include <cstring>
    
    #define LL long long
    #define ls nod<<1
    #define rs (nod<<1)+1
    #define pii pair<int,int>
    #define mp make_pair
    #define pb push_back
    #define INF 0x3f3f3f3f
    
    const double eps = 1e-10;
    const int maxn = 1e3 + 10;
    const LL mod = 1e9 + 7;
    
    int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;}
    using namespace std;
    
    int a[maxn],b[maxn];
    int f[maxn][6*maxn];
    
    int main() {
        ios::sync_with_stdio(false);
        int n;
        cin >> n;
        int tot = 0;
        for (int i = 1;i <= n;i++) {
            cin >> a[i] >> b[i];
            tot += (a[i] + b[i]);
        }
        for (int i = 0;i <= n;i++) {
            for (int j = 0;j <= 6*n;j++)
                f[i][j] = INF;
        }
        f[1][b[1]] = 1;
        f[1][a[1]] = 0;
        for (int i = 2;i <= n;i++) {
            for (int j = 0;j <= 6*n;j++) {
                if (j >= a[i])
                    f[i][j] = min(f[i][j],f[i-1][j-a[i]]);
                if (j >= b[i])
                    f[i][j] = min(f[i][j],f[i-1][j-b[i]]+1);
            }
        }
        int Minn = INF;
        int ans = INF;
        for (int i = 0;i <= tot;i++) {
            if (f[n][i] != INF) {
                if (abs(i-(tot-i)) < Minn) {
                    Minn = abs(i-(tot-i));
                    ans = f[n][i];
                }
                else if (abs(i-(tot-i)) == Minn)
                    ans = min(ans,f[n][i]);
            }
        }
        cout << ans << endl;
        return 0;
    }
  • 相关阅读:
    WIN10 UBUNTU 异常:sleep: cannot read realtime clock: Invalid argument
    Mysql表名大小写忽略
    Spring boot自定义配置文件并映射到指定类中
    list addAll产生异常java.lang.UnsupportedOperationException
    Oracle extract函数提取时分秒的问题
    JOOQ默认schema
    Druid数据库连接失败,无限尝试问题
    Mysql安装后root无法登陆(Access denied for user 'root'@'localhost')
    JavaSE第17篇:集合之Map集合
    JavaSE第16篇:集合之Collection集合下篇
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/12459224.html
Copyright © 2011-2022 走看看