容斥原理
- 例题:
- luogu p1450 硬币购物:
- 题目描述
共有4种硬币。面值分别为c1->,c4。某人去商店买东西,去了tot次。每次带di枚ci硬币,买si的价值的东西。问每次有多少种付款方案。
输入格式:
第一行 c1,c2,c3,c4,tot 下面tot行 d1,d2,d3,d4,s
输出格式:
每次的方法数
输入样例#1: 复制
1 2 5 10 2
3 2 3 1 10
1000 2 2 2 900
输出样例#1: 复制
4
27
解:
先求一个完全背包求方案数,因为每次选的物品是无限的。而题目要求每件只能选d[i]种,所以答案要减去不满足的情况。
因为完全背包的递推式:f[j] += f[j-c[i]],所以只要有了d{i]+1件,其余的可以任选。所以减去f[(d[i]+1)*c[i]];
还要注意(奇数次操作是减,偶数次操作是加)
杨辉三角:
1.用到全部组合数。
for (int i = 0;i <= n;i++)
{
c[i][0] = 1;
for (int i = 1;i <= i;j++) c[i][j] = c[i-1][j-1] + c[i-1][j];
}
2.用到一行的组合数。(在n个中取i个)
公式:
n − k + 1 k C n k − 1 \frac{n-k+1}{k}C_{n}^{k-1}\qquad kn−k+1Cnk−1
c[0] = 0;
for (int i = 1;i <= n;i++) c[i] = c[i-1]*(n-i+1)/i;//一定要先乘后除。防止除法去尾。
求约数个数:
ans = ∏ i = 1 k ( a [ i ] + 1 ) \prod_{i=1}^k(a[i]+1) ∏i=1k(a[i]+1)
欧拉函数
1.求单个欧拉函数。
int euler_phi(int n)
{
int m = sqrt(n);
int ans = n;
for (int i = 2;i <= m;i++) if(n%i == 0 ) {
ans = ans /i * (i-1);
while(n%i == 0) n/= i;
}
if( n > 1 ) ans = ans / n * (n-1);
return ans;
}
2.欧拉筛:
void euler_table(int n)
{
phi[1] = 1;
for (int i = 2;i <= n;i++) if(!phi[i])
for (int j = i;j <= n;j+=i)
{
if(!phi[j]) phi[j] = j;
phi[j] = ph[j]/i * (i-1);
}
}
数学的题目 = 打表找规律+随便xiajiba乱分析;