首页 > 代码库 > [luoguP1282] 多米诺骨牌(DP + 背包)
[luoguP1282] 多米诺骨牌(DP + 背包)
传送门
将问题转换成分组背包,每一组有上下两个,每一组中必须选则一个,上面的价值为0,下面的价值为1,求价值最小
因为要求上下两部分差值最小,只需从背包大小为总数 / 2 时往前枚举,找最小答案即可。
——代码
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #define N 100001 5 #define min(x, y) ((x) < (y) ? (x) : (y)) 6 #define max(x, y) ((x) > (y) ? (x) : (y)) 7 8 int n, m, tot, ans; 9 int a[N], b[N], f[N];10 11 inline int read()12 {13 int x = 0, f = 1;14 char ch = getchar();15 for(; !isdigit(ch); ch = getchar()) if(ch == ‘-‘) f = -1;16 for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - ‘0‘;17 return x * f;18 }19 20 int main()21 {22 int i, j, tmp;23 n = read();24 memset(f, 127 / 3, sizeof(f));25 for(i = 1; i <= n; i++)26 {27 tot += a[i] = read();28 tot += b[i] = read();29 m += max(a[i], b[i]);30 }31 f[0] = 0;32 for(i = 1; i <= n; i++)33 for(j = m; j >= 0; j--)34 {35 tmp = 1e9;36 if(j >= a[i]) tmp = min(tmp, f[j - a[i]]);37 if(j >= b[i]) tmp = min(tmp, f[j - b[i]] + 1);38 f[j] = tmp;39 }40 for(i = tot >> 1;;i--)41 {42 ans = min(f[i], f[tot - i]);43 if(ans < 1e9)44 {45 printf("%d\n", ans);46 return 0;47 }48 }49 }
[luoguP1282] 多米诺骨牌(DP + 背包)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。