POJ 1014 Dividing
来源:互联网 发布:表格筛选重复数据 编辑:程序博客网 时间:2024/04/30 06:20
Dividing
题目意思很清楚,这里就不再翻译了。初始的时候,我将他当作分组背包(估计是最近做分组背包做的太多了),来解,但一直超时,后来分析了一下时间复杂度为O(v*n),看了一下数据后,发现根本不可能过的去,v最大可有90000,而n最大有20000,这样怎么可能过的去。。。。。。后来看别人的解题报告的时候,发现可以用多重背包。然后我就对比了一下两者的情况。用分组背包的时候是这么考虑的:每类物品中可以选取一件,也可以选取两件。。。。而这些选择之间是互斥的,所以可用分组背包,而用多重背包更没问题。不过这个题目,用多重背包会更快,多重背包的复杂度为:O(v*sum(log num[i])),所以,直接按照模版写就可以过了。
#include <stdio.h>#include <string.h>int num[10] ;int sum ;int dp[100000] ;int tag ;#define INF -100000000bool read(){ bool flag = 0 ; sum = 0 ; for(int i = 1 ; i <= 6 ; i ++){ scanf("%d" , &num[i]) ; sum += num[i] * i ; if(num[i]) flag = 1 ; } return flag ;}inline int max(int a , int b){ return a > b ? a : b ;}void ZeroOnePack(int cost , int weight){ for(int v = sum/2 ; v >= cost ; v--){ dp[v] = max(dp[v] , dp[v-cost] + weight) ; if(dp[v]==sum/2){ tag = 1 ; return ; } }}void CompletePack(int cost , int weight){ for(int v = cost ; v <= sum/2 ; v ++){ dp[v] = max(dp[v] , dp[v-cost] + weight) ; if(dp[v]== sum/2){ tag = 1 ; return ; } }}void MultiplePack(int cost ,int weight ,int amount){ if(cost * amount >= sum/2){ CompletePack(cost , weight) ; return ; } int k(1) ; while(k < amount){ ZeroOnePack(k * cost , k * weight) ; if(tag) return ; amount = amount - k ; k = k * 2 ; } ZeroOnePack(amount * cost , amount * weight) ; return ;}void solve(){ //init if(sum%2){ printf("Can't be divided.\n"); return ; } tag = 0 ; for(int i = 1 ; i <= sum/2 ; i ++) dp[i] = INF ; for(int i = 1 ; i <= 6 ; i ++){ MultiplePack(i , i , num[i]) ; if(tag) break ; } if(tag){ printf("Can be divided.\n") ; } else{ printf("Can't be divided.\n") ; }}int main(){ int t(0) ; while(read()){ printf("Collection #%d:\n" , ++t) ; solve() ; printf("\n") ; } return 0 ;}
然而这个题目也可以有其他的解法:直接搜索,不过需要注意剪枝。
#include <stdio.h>#include <string.h>int num[10] ;int sum ;int tag ;bool read(){ bool flag = 0 ; sum = 0 ; for(int i = 1 ; i <= 6 ; i ++){ scanf("%d" , &num[i]) ; if(num[i]) flag = 1 ; sum += i * num[i] ; } return flag ;}void dfs(int c , int v){ if(v==sum / 2){ tag = 1 ; return ; } if(tag) return ; for(int i = c ; i >= 1 ; i --){ if(num[i]){ if(v + i <= sum / 2){ num[i] -- ; dfs(c , v + i) ; if(tag) return ; } } } return ;}void solve(){ tag = 0 ; if(sum%2){ printf("Can't be divided.\n") ; return ; } dfs(6 , 0) ; if(tag){ printf("Can be divided.\n") ; } else{ printf("Can't be divided.\n") ; }}int main(){ int t(0) ; while(read()){ printf("Collection #%d:\n" , ++t) ; solve() ; printf("\n") ; } return 0 ;}
- POJ 1014 Dividing
- POJ 1014 Dividing
- poj 1014 Dividing
- poj 1014Dividing
- POJ 1014 Dividing
- POJ 1014 Dividing
- POJ 1014 Dividing
- poj 1014 Dividing
- Poj 1014 Dividing
- POJ 1014 Dividing
- POJ 1014 Dividing
- poj 1014 Dividing
- POJ-1014-Dividing
- POJ 1014 dividing
- poj 1014 Dividing
- POJ-1014-Dividing
- POJ 1014 -- Dividing
- POJ 1014 Dividing 解答
- HTML5 canvas 初级入门教程
- 注册用户控件和母板页关联,Ajax局部更新
- javascript 正则表达式入门基础—由浅入深
- 开发者所需要知道的iOS6 SDK新特性
- 轻量级(Lightweight)
- POJ 1014 Dividing
- 品牌标志形象的延展--海报应用实例解析
- oracle字符突然非正常输入了
- Ubuntu下环境变量该写进哪个文件里
- 拥塞控制和流量控制的区别
- iPhone开发中关于Nib文件讲解
- C/C++领域速度最快的程序诊断日志库 Pantheios 介绍
- Linux常见面试题
- 用DCMTK解压jpeg压缩图像