整数划分解题报告
2011-04-24 19:43
211 查看
--- 整数划分解报告 ---- By Debugcool
-------------------------------------------------------
1.问题描述:
给定一个正整数N和K
1.> 将n划分成若干正整数之和的划分数。
2.> 将n划分成k个正整数之和的划分数。
3.> 将n划分成最大数不超过k的划分数。
4.> 将n划分成若干奇正整数之和的划分数。
5.> 将n划分成若干不同整数之和的划分数。
2.问题分类:总的来说这些都是背包问题;
第一个问:就是一个完全背包,背包有 1 --- N 种,第 i 种背包的重量为 i ,价值为 i ;这很好解决:
dp[0] = 1;
for (i = 1;i <= N;i++)
for (j = i;j <= N;j++)
dp[j] += dp[j-i];
其中 dp[j] 是用前 i 个数能构成 j 的种类数,则结果就为 dp
看完这个问题了,那么 第3个问就知道了 , 即用前 K 种背包来装 所得结果,只需把第一层循环的 i <= N 改为 i <= K 即可;
dp[0] = 1;
for (i = 1;i <= K;i++)
for (j = i;j <= N;j++)
dp[j] += dp[j-i]; 结果同样为 dp
;
那么第四个问呢,想想是奇数,那么 i = 2,4,6,…… 等等值就不能取了,因为这些背包种类不合要求,这很简单啊 i++ 改为 i += 2 不就行了;
dp[0] = 1;
for (i = 1;i <= N;i+=2)
for (j = i;j <= N;j++)
dp[j] += dp[j-i]; 结果同样为 dp
;
再看看第五个问,若干个不同的???想到了什么,就是一种背包最多只能用一次???这是什么,经典的 01背包 啊,与第一个问的不同就是第二层循环的顺序而已;
dp[0] = 1;
for (i = 1;i <= N;i++)
for (j = n;j >= i ;j--)
dp[j] += dp[j-i];
最后我们来思考第二个问:
要求只要 K 个,这怎么办呢???想想特殊情况…… 如果 K = 1 呢,只能是 N 咯,若果 N = 0 呢, 结果只能是 0 中可能啊,那同样N < K 的话,不可能分啊 结果为 0 ,好,特殊的考虑完了,那么我们再考虑,分的结果中有没有 1 , 如果有 那么就把剩下的 N - 1 分成 K - 1 份 , 如果没有呢,那么我们先拿出 K 份 给每一堆 一个1, 再把剩下的 N - K 分成 K 份就行了啊,好了,至此,递归方法出来了:
int work(int n,int k)
{
if (k == 1)
return 1;
if (n == 0)
return 0;
if (n < k)
return 0;
return work(n-k,k) + work(n-1,k-1);
}
--------------------------------
总结:背包问题是基础啊~~~
Debugcool---------------
-------------------------------------------------------
1.问题描述:
给定一个正整数N和K
1.> 将n划分成若干正整数之和的划分数。
2.> 将n划分成k个正整数之和的划分数。
3.> 将n划分成最大数不超过k的划分数。
4.> 将n划分成若干奇正整数之和的划分数。
5.> 将n划分成若干不同整数之和的划分数。
2.问题分类:总的来说这些都是背包问题;
第一个问:就是一个完全背包,背包有 1 --- N 种,第 i 种背包的重量为 i ,价值为 i ;这很好解决:
dp[0] = 1;
for (i = 1;i <= N;i++)
for (j = i;j <= N;j++)
dp[j] += dp[j-i];
其中 dp[j] 是用前 i 个数能构成 j 的种类数,则结果就为 dp
看完这个问题了,那么 第3个问就知道了 , 即用前 K 种背包来装 所得结果,只需把第一层循环的 i <= N 改为 i <= K 即可;
dp[0] = 1;
for (i = 1;i <= K;i++)
for (j = i;j <= N;j++)
dp[j] += dp[j-i]; 结果同样为 dp
;
那么第四个问呢,想想是奇数,那么 i = 2,4,6,…… 等等值就不能取了,因为这些背包种类不合要求,这很简单啊 i++ 改为 i += 2 不就行了;
dp[0] = 1;
for (i = 1;i <= N;i+=2)
for (j = i;j <= N;j++)
dp[j] += dp[j-i]; 结果同样为 dp
;
再看看第五个问,若干个不同的???想到了什么,就是一种背包最多只能用一次???这是什么,经典的 01背包 啊,与第一个问的不同就是第二层循环的顺序而已;
dp[0] = 1;
for (i = 1;i <= N;i++)
for (j = n;j >= i ;j--)
dp[j] += dp[j-i];
最后我们来思考第二个问:
要求只要 K 个,这怎么办呢???想想特殊情况…… 如果 K = 1 呢,只能是 N 咯,若果 N = 0 呢, 结果只能是 0 中可能啊,那同样N < K 的话,不可能分啊 结果为 0 ,好,特殊的考虑完了,那么我们再考虑,分的结果中有没有 1 , 如果有 那么就把剩下的 N - 1 分成 K - 1 份 , 如果没有呢,那么我们先拿出 K 份 给每一堆 一个1, 再把剩下的 N - K 分成 K 份就行了啊,好了,至此,递归方法出来了:
int work(int n,int k)
{
if (k == 1)
return 1;
if (n == 0)
return 0;
if (n < k)
return 0;
return work(n-k,k) + work(n-1,k-1);
}
--------------------------------
总结:背包问题是基础啊~~~
Debugcool---------------
相关文章推荐
- 解题报告 整数划分
- 整数划分解题报告
- 整数分解和划分 - 兼 ACM PKU POJ 1221 解题报告
- 整数划分解题报告(DP方法)
- Leetcode 397. Integer Replacement 整数替换 解题报告
- 土地划分 解题报告
- 浙大PAT 1006. 换个格式输出整数 (解题报告)
- POJ 1503(高精度整数加法) 解题报告
- Leetcode #29 Divide Two Integers 整数相除 解题报告
- NOIP 2001 数的划分 解题报告
- 【原】 POJ 1001 Exponentiation 大整数乘法 解题报告
- POJ 1503(高精度整数加法) 解题报告
- 【九度OJ】题目1190:大整数排序 解题报告
- POJ 1001 解题报告 高精度大整数乘法模版
- 数的划分解题报告
- 【codevs1779】 单词的划分 解题报告
- 【集合划分】解题报告
- POJ 1001 解题报告 高精度大整数乘法模版
- 【原】 POJ 1503 Integer Inquiry 大整数加法 解题报告
- NOIP 2001数的划分 解题报告(划分型DP)