标签:
Description
Input
Output
Sample Input
Sample Output
题目大意就是判断这么多数字能不能均分成两类,每个数字不可拆分。
看完题目就感觉是个多重背包。不过这里只用判断sum/2能否被装到。于是就不用判断sum/2+1到sum的背包了。
由于只用判断是否能装到,于是只用开bool型数组即可。
由于每个数字有一定的使用次数,所以需要开vis数组,而且对于每一种数字的背包需要初始化全为1。
由于考虑到需要最优解,所以对于dp[j]为真的情况,就不需要再判断dp[j-i]了,因为如果再靠dp[j-i]来放下num[i]的话,就浪费了一次数字i的使用。
代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #define N 1000000007 using namespace std; int num[7], sum; int vis[60005]; bool dp[60005]; bool Input() { sum = 0; memset(dp, 0, sizeof(dp)); for (int i = 1; i <= 6; ++i) { scanf("%d", &num[i]); sum += i*num[i]; } if (sum) return true; else return false; } void Work() { if (sum % 2) { printf("Can‘t be divided.\n\n"); return; } sum /= 2; dp[0] = true; for (int i = 1; i <= 6; ++i) { if (num[i] == 0) continue; memset(vis, 0, sizeof(vis)); for (int j = i; j <= sum; j++) { if (dp[j-i] && !dp[j] && vis[j-i] < num[i]) { dp[j] = true; vis[j] = vis[j-i]+1; } } } if (dp[sum]) printf("Can be divided.\n\n"); else printf("Can‘t be divided.\n\n"); } int main() { //freopen("test.in", "r", stdin); int times = 1; while (Input()) { printf("Collection #%d:\n", times); Work(); times++; } return 0; }
ACM学习历程—HDU 1059 Dividing(dp && 多重背包)
标签:
原文地址:http://www.cnblogs.com/andyqsmart/p/4517673.html