HDU 4651&&HDU 4658 五边形数定理
2016-04-26 22:02
375 查看
Partition
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1079 Accepted Submission(s): 630
Problem Description
How many ways can the numbers 1 to 15 be added together to make 15? The technical term for what you are asking is the "number of partition" which is often called P(n). A partition of n is a collection of positive integers (not necessarily distinct) whose sum
equals n.
Now, I will give you a number n, and please tell me P(n) mod 1000000007.
Input
The first line contains a number T(1 ≤ T ≤ 100), which is the number of the case number. The next T lines, each line contains a number n(1 ≤ n ≤ 105) you need to consider.
Output
For each n, output P(n) in a single line.
Sample Input
4
5
11
15
19
Sample Output
7
56
176
490
Source
2013 Multi-University Training Contest 5
HDU4651求的是正整数分解,可以有重复元素。(没有重复元素的考虑dp,dp[i][j]表示j个数组成i的个数,有dp[i][j]=dp[i-j][j-1]+dp[i-j][j],分别考虑j在不在里面)。
首先,欧拉函数(1-x)(1-x^2)(1-x^3)…=1 – x - x^2 + x^5 + x^7 –x^12 – x^15…. X的系数为k*(3*k+1)/2,k*(3*k+1)/2留下来的次方正好是五边形数
然后欧拉函数的倒数是分割函数的母函数,假设p(k)为k的分割数,推过来就有
(1-x- x^2 +x^5 +x^7 –x^12 –x^15 + x^22 + x^26+ …)(1+ p(1)*x + p(2)*x^2 + p(3)*x^3 +…) = 1
比较等式两边的系数,可得到p(n)-p(n-1)-p(n-2)+p(n-5)+p(n-7)+…=0
代码:
#pragma warning(disable:4996)
#include <iostream>
#include <functional>
#include <algorithm>
#include <cstring>
#include <vector>
#include <string>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <deque>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
#define INF 0x333f3f3f
#define repp(i, n, m) for (int i = n; i <= m; i++)
#define rep(i, n, m) for (int i = n; i < m; i++)
#define sa(n) scanf("%d", &(n))
const ll mod = 1e9 + 7;
const int maxn = 1e5 + 5;
const double PI = acos(-1.0);
int n;
int k[maxn];
ll res[maxn];
void init()
{
int i, j;
int num = 0;
for (i = 1; i <= 1000; i++)
{
for (j = 1; j <= 2; j++)
{
if (j & 1)
{
k[num] = i*(3 * i - 1) / 2;
num++;
}
else
{
k[num] = i*(3 * i + 1) / 2;
num++;
}
}
}
res[0] = 1;
for (i = 1; i <= 100000; i++)
{
for (j = 0; j < num; j++)
{
if (i - k[j] >= 0)
{
if (j % 4 < 2)
{
res[i] += (res[i - k[j]]) % mod;
res[i] %= mod;
}
else
{
res[i] -= (res[i - k[j]]) % mod;
res[i] = (res[i] % mod + mod) % mod;
}
}
else
{
break;
}
}
}
}
void solve()
{
int n;
sa(n);
printf("%lld\n", res
);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("i.txt", "r", stdin);
freopen("o.txt", "w", stdout);
#endif
init();
int t;
scanf("%d", &t);
while (t--)
{
solve();
}
return 0;
}
Integer Partition
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 574 Accepted Submission(s): 267
Problem Description
Given n, k, calculate the number of different (unordered) partitions of n such that no part is repeated k or more times.
Input
First line, number of test cases, T.
Following are T lines. Each line contains two numbers, n and k.
1<=n,k,T<=105
Output
T lines, each line contains answer to the responding test case.
Since the numbers can be very large, you should output them modulo 109+7.
Sample Input
4
4 2
4 3
4 4
4 5
Sample Output
2
4
4
5
Source
2013 Multi-University Training Contest 6
HDU4658参考了http://blog.csdn.net/whai362/article/details/42530243这篇博客,这个题的母函数
G(x)=( 1 + x + x^2 +...+ x^(k-1) ) * ( 1 + x^2 +x^4 +...+ x^((k-1)*2) ) *...
=(1-x^k)/(1-x) * (1-x^(k*2))/(1-x^2)* ...
=( (1-x^k) * (1-(x^k)^2) *... ) / ((1-x) * (1-x^2) *... )
=Q(x^k)/Q(x) (Q(x)为欧拉函数,根据上述定理可得)
=Q(x^k)*P(x)
=( 1 - x^k - (x^k)^2 + (x^k)^5 +(x^k)^7 -... ) * ( 1 + x + 2*x^2 + 3*x^3 + 5*x^4 + 7*x^5 + ... )
代码:
#pragma warning(disable:4996)
#include <iostream>
#include <functional>
#include <algorithm>
#include <cstring>
#include <vector>
#include <string>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <deque>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
#define INF 0x333f3f3f
#define repp(i, n, m) for (int i = n; i <= m; i++)
#define rep(i, n, m) for (int i = n; i < m; i++)
#define sa(n) scanf("%d", &(n))
const ll mod = 1e9 + 7;
const int maxn = 1e5 + 5;
const double PI = acos(-1.0);
int n;
int k[maxn];
int res[maxn];
void init()
{
int i, j;
int num = 0;
for (i = 1; i <= 1000; i++)
{
for (j = 1; j <= 2; j++)
{
if (j & 1)
{
num++;
k[num] = i*(3 * i - 1) / 2;
}
else
{
num++;
k[num] = i*(3 * i + 1) / 2;
}
}
}
res[0] = 1;
for (i = 1; i <= 100000; i++)
{
for (j = 1; j <= num; j++)
{
if (i - k[j] >= 0)
{
if ((j-1) % 4 < 2)
{
res[i] += (res[i - k[j]]);
if (res[i] >= mod)
res[i] -= mod;
}
else
{
res[i] -= (res[i - k[j]]);
if (res[i] < 0)
res[i] += mod;
}
}
else
{
break;
}
}
}
}
void solve()
{
int n, kk;
int i, j;
int ans;
sa(n), sa(kk);
ans = res
;
for (i = 1;; i++)
{
int t = kk*k[i];
if (t > n)
break;
if ((i - 1) % 4 < 2)
{
ans = (ans - res[n - t] + mod) % mod;
}
else
{
ans = (ans + res[n - t]) % mod;
}
}
printf("%d\n", ans);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("i.txt", "r", stdin);
freopen("o.txt", "w", stdout);
#endif
init();
int t;
scanf("%d", &t);
while (t--)
{
solve();
}
//system("pause");
return 0;
}
相关文章推荐
- Oracle查询练习1
- 类对象数组以及排序问题
- bootstrap样式大全
- 二叉树的镜像
- 单选按钮和标签组合点击
- 向大学说拜拜——大学 > 兴趣 + 时间 + 思考 + 实践
- 每日工作总结08
- lower_bound & upper_bound
- 运行jar包
- $rootScope.somevalue
- XDU-1153 万神的线段 (排序)
- 动画
- 冲刺第九天
- Django:之CMDB资源系统
- 一个Mathematica能解、maple不行的高阶线性常微分方程
- 关于一些实验班问题的解答以及下个学期之前小组的任务
- 非阻塞模式
- spring+redis做数据缓存
- LSA校验和计算(java源码)
- 使用Xutils无法访问HttpRequestBase 找不到org.apache.http.client.methods.HttpRequestBase的类文件