HDU 1059 (DP)
2015-11-16 23:51
197 查看
题意是有价值1-6的大理石,告诉你每种价值的个数问能不能分成总价值相同的两堆。
首先每种石头需要计算的个数不会超过6个。
比如对于1,如果最后分成的两堆都有1,那么我们可以预先把相同数量的1拿掉,最后使得只剩下某一堆中含有1,那么最多含有多少呢?应该是5。因为如果有大于等于6的1,那么我们总可以在另一堆中拿掉一块大理石,那后这一堆中拿掉相应数量的1补偿。所以1最多只有5块。
比如对于2,同样的我们假设只有一堆里面有2,那么最多有多少数量呢?如果另一堆里面有4或者6,那么我们总可以拿掉一个6或者4,然后在这一堆拿掉等价的2,也就是另一堆有4或者6的话这一堆最多只能有1个2。同样的另一堆有3和5同时存在的话,这一堆2最多只有3个。
经过这些分析发现其实每一堆的石头其实有很多都是没用的,所以我们可以模掉一个数。然后可以用最基本的DP解决了。
首先每种石头需要计算的个数不会超过6个。
比如对于1,如果最后分成的两堆都有1,那么我们可以预先把相同数量的1拿掉,最后使得只剩下某一堆中含有1,那么最多含有多少呢?应该是5。因为如果有大于等于6的1,那么我们总可以在另一堆中拿掉一块大理石,那后这一堆中拿掉相应数量的1补偿。所以1最多只有5块。
比如对于2,同样的我们假设只有一堆里面有2,那么最多有多少数量呢?如果另一堆里面有4或者6,那么我们总可以拿掉一个6或者4,然后在这一堆拿掉等价的2,也就是另一堆有4或者6的话这一堆最多只能有1个2。同样的另一堆有3和5同时存在的话,这一堆2最多只有3个。
经过这些分析发现其实每一堆的石头其实有很多都是没用的,所以我们可以模掉一个数。然后可以用最基本的DP解决了。
#include <bits/stdc++.h> using namespace std; #define maxn 121111 bool dp[maxn]; int a[maxn], tot; int main () { //freopen ("in", "r", stdin); int kase = 0; while (1) { bool ok = 0; tot = 0; for (int i = 1; i <= 6; i++) { int num; scanf ("%d", &num); if (num != 0) ok = 1; if (num > 6) { num %= 6; if (num == 0) num = 6; } for (int j = 0; j < num; j++) a[++tot] = i; } if (!ok) break; memset (dp, 0, sizeof dp); dp[0] = 1; int sum = 0; for (int i = 1; i < tot; i++) { for (int j = sum; j >= 0; j--) { if (dp[j]) dp[j+a[i]] = 1; } sum += a[i]; } sum = 0; for (int i = 1; i <= tot; i++) sum += a[i]; printf ("Collection #%d:\n", ++kase); if ((sum&1) || dp[sum>>1] == 0) printf ("Can't be divided.\n"); else printf ("Can be divided.\n"); printf ("\n"); } return 0; }
相关文章推荐
- Redis学习笔记(1)
- JAVA基础课总结四
- pthread_join()和pthread_detach()
- Linux 文件属性详细介绍
- 多网卡的7种bond模式原理
- HNOI2002 营业额统计
- WebKit之IDL分析
- map与unordered_map的区别与选择
- 第一次实验报告
- 一起talk C栗子吧(第六十一回:C语言实例--字符串连接)
- JAVA基础课总结三
- Huffman树
- 南昌大学软院大神养成计划----网页制作学习课程一心得
- 杭电ACM 1090
- Android之用HttpURLConnection参数以XML形式封装的部分关键代码
- JAVA基础课总结二
- 文件命令复习(一)
- centos 5.x install vestaCP 0.9.18-15
- [super dealloc]内存释放的先后顺序
- Unique Paths -leetcode