zoukankan      html  css  js  c++  java
  • 洛谷 P1282 多米诺骨牌 (01背包)

    题目链接:https://www.luogu.com.cn/problem/P1282

    每个骨牌都有翻转或不翻转两种状态,体积分别为 (a[i]-b[i])(b[i]-a[i]) 可以为负,代价分别为 (0)(1),最终要求使体积绝对值最小的代价最小

    (dp[i][j]) 表示前 (i) 个骨牌,体积为 (j) 时的最小代价,(01) 背包转移即可,注意负坐标要偏移

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int maxn = 1010;
    const int INF = 0x3f3f3f3f;
    
    int n;
    int a[maxn], b[maxn]; 
    int dp[maxn][30*maxn];
    
    ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; }
    
    int main(){
    	n = read();
    	for(int i = 1 ; i <= n ; ++i) a[i] = read(), b[i] = read();
    	
    	memset(dp, 0x3f, sizeof(dp)); 
    	
    	dp[0][0+7000] = 0;
    	for(int i = 1 ; i <= n ; ++i){
    		for(int j = 7000 ; j >= -7000 ; --j){
    			if(dp[i-1][j-(a[i]-b[i])+7000] != INF) dp[i][j+7000] = min(dp[i][j+7000], dp[i-1][j-(a[i]-b[i])+7000]); // 不转 
    			if(dp[i-1][j-(b[i]-a[i])+7000] != INF) dp[i][j+7000] = min(dp[i][j+7000], dp[i-1][j-(b[i]-a[i])+7000] + 1); // 转 
    		}
    	}
    	
    	int ans = INF; int flag = 0;
    	for(int i = 0 ; i <= 6000 ; ++i){
    		if(dp[n][i+7000] != INF) {
    			ans = min(ans, dp[n][i+7000]);
    			flag = 1;
    		}
    		if(dp[n][-i+7000] != INF) {
    			ans = min(ans, dp[n][-i+7000]);
    			flag = 1;
    			break;
    		}
    		if(flag) break;
    	}
    	printf("%d
    ", ans);
    	
    	return 0;
    }
    
  • 相关阅读:
    [ZJOI 2012]数列
    [JSOI 2011]柠檬
    sonar错误及修改方案
    mysql 查询该字段不包含中文
    service 事务
    mysql 不等于和null
    java文件编译为class文件
    主,副时间排序
    MySQL 按首字母排序
    excle导入
  • 原文地址:https://www.cnblogs.com/tuchen/p/15063946.html
Copyright © 2011-2022 走看看