1、poj-1664(递归)
思路:递归求解
先判断特殊情况,如果n<m,结果是0
否则,进行递归求解,每次减去一个值,如果小于0,就返回;
如果总和等于m并且不超过n次,就符合条件cnt++。
#include<iostream>
#include<cstdio>
using namespace std;
int n,m,cnt;
void f(int res,int num,int tp)
{
if(res==0)
{
cnt++;
return ;
}
if(num==0) return ;
for(int i=1;i<=m;i++)
{
if(i>=tp&&res>=i) f(res-i,num-1,i);
}
}
int main(void)
{
int k;
cin>>k;
while(k--)
{
cin>>m>>n;
if(m<n)
{
cout<<0<<endl;
continue;
}
cnt=0;
f(m,n,1);
cout<<cnt<<endl;
}
return 0;
}
2、hdu-2064(递归)
思路:
n=1,只有一种摆法;n=2,有两种摆法;
n=3,去掉一个就变成n=2的情况,去掉两个就变为n=1的情况
以此类推,F(n)=F(n-1)+F(n-2);
注意:long long类型。
3、hdu-2048(错排问题)
错排问题:
n个有序的元素有n!个不同的排序,如果一个排序使所有元素不在原来的位置上,
称为错排问题。
eg:
序列 1,2的错排个数为1;1,2,3的错排个数为2
1,2,3的错排序列可以视为2,1(1,2的错排序列)与3交换位置得到的(2,1,3;1和2分别于3交换位置得到
3,1,2和2,3,1)。
递推公式:F(n)=(n-1)*(F(n-1)+F(n-2));
证明:
(1)考虑n个元素,把它放到位置k,共有n-1种放法
(2)考虑第k个元素,如果第k个元素放到位置n,就有n-2个元素还没有位置,共F(n-2)种情况;
如果第k个元素不放到位置n,就有n-1个元素还没有位置,共F(n-1)种情况。
所以F(n)=(n-1)*(F(n-1)+F(n-2))。
由容斥原理推出递推公式:D(n) = n! (1/0! - 1/1! + 1/2! - 1/3! + 1/4! + …… + (-1)^n/n!)。
本题思路:我用想求出所有情况n!,再求出错排序的情况F(n)(我用的递推)。
#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
typedef long long LL;
int main(void)
{
LL a[120],n,t,i;
a[0]=0;a[1]=0;a[2]=1;
scanf("%lld",&t);
while(t--)
{
scanf("%d",&n);
double sum=1.0;
for(i=2;i<=n;i++) sum*=i;
for(i=3;i<=n;i++) a[i]=(i-1)*(a[i-1]+a[i-2]);
printf("%.2lf%%\n",100.0*a[n]/sum);
}
return 0;
}