(经典)POJ-3181 完全背包+大数处理
2016-05-14 16:26
197 查看
题目大意:给定N,K,用1-K组成N,一共有多少组合方法?
题目链接:点击打开链接
分析:
这题属于完全部分和问题,其实也可以理解为划分数问题。如n为3,k为2时,有
1+2
1+1+1 这2种方法,我们可以理解为用1和2去填满或者组成3,这样想便是完全背包可行性也就是完全部分和问题。
或者这样看,
1|11
1|1|1 这样的话便是一个划分数问题,即将n个1划分组且每组最多k个的问题,利用逆向思想,我们常常将划分数问题转化为完全部分和问题来求解(即划分与组合是个可逆的过程)。
状态:dp[i][j]前i种物品(1-i价格)花费j元的种数
决策:第i种不买或者至少买一个
转移:
不买的话显然为dp[i-1][j]
至少买一个的话为dp[i][j-i](注意与多重问题的区别,想一想为什么)
所以 dp[i][j] = dp[i-1][j] + dp[i][j-i],最终提交还是错了,自己输出一些数据测试发现出现了不正常的数说明很有可能溢出了,可是如果写一个高精度的话肯定是要TLE的。在网上看到一种很巧妙的方法,由于最大结果也只有33位(别人说的。。),long long可以存储19位,所以可以利用2个long long来存一个33位+的数,具体实现也很简单,直接看代码吧。
附上代码:
题目链接:点击打开链接
分析:
这题属于完全部分和问题,其实也可以理解为划分数问题。如n为3,k为2时,有
1+2
1+1+1 这2种方法,我们可以理解为用1和2去填满或者组成3,这样想便是完全背包可行性也就是完全部分和问题。
或者这样看,
1|11
1|1|1 这样的话便是一个划分数问题,即将n个1划分组且每组最多k个的问题,利用逆向思想,我们常常将划分数问题转化为完全部分和问题来求解(即划分与组合是个可逆的过程)。
状态:dp[i][j]前i种物品(1-i价格)花费j元的种数
决策:第i种不买或者至少买一个
转移:
不买的话显然为dp[i-1][j]
至少买一个的话为dp[i][j-i](注意与多重问题的区别,想一想为什么)
所以 dp[i][j] = dp[i-1][j] + dp[i][j-i],最终提交还是错了,自己输出一些数据测试发现出现了不正常的数说明很有可能溢出了,可是如果写一个高精度的话肯定是要TLE的。在网上看到一种很巧妙的方法,由于最大结果也只有33位(别人说的。。),long long可以存储19位,所以可以利用2个long long来存一个33位+的数,具体实现也很简单,直接看代码吧。
附上代码:
#include<iostream> using namespace std; int n, k; long long MOD = 1; long long dp1[1005], dp2[1005]; int main() { scanf("%d%d", &n, &k); for (int i = 0; i < 18; i++) MOD *= 10; dp2[0] = 1; for (int i = 1; i <= k; i++) for (int j = 0; j <= n; j++) { if (j - i >= 0) { dp1[j] = dp1[j] + dp1[j - i] + (dp2[j] + dp2[j - i]) / MOD; //算出i,j对应的高位 dp2[j] = (dp2[j] + dp2[j - i]) % MOD; //算出低位 } else { dp1[j] = dp1[j]; dp2[j] = dp2[j]; } } if (dp1 ) printf("%lld", dp1 ); printf("%lld\n", dp2 ); return 0; }
相关文章推荐
- 人为删除控制文件故障模拟
- 圆柱
- 亚马逊 在线笔试 2014-10-9 比较扑克牌序列
- 栈
- thinkphp3.2,URL重写
- activiti 自定义用户、组
- ios开发学习笔记--Core Motion
- GDOI2016 Day1 T2 最长公共子串
- 网络请求——XML解析
- 常见排序算法(二)
- Java并发编程:阻塞队列
- Open-E DSS V7 应用系列之二 系统安装
- Open-E DSS V7 应用系列之二 系统安装
- PHP 升级到5.5后MySQL的代替法
- ROS_DHCP添加路由
- App Links
- Activity和Fragment的生命周期
- Condition线程通信
- 关于scrollview 镶嵌linearlayout布局的控件位于底部的问题 关于scrollview镶嵌RelativeLayout布局失效
- Synchronized关键字