史前文明
题目描述
明明和白白是好朋友,他们经常在一起商量数学问题。
明明和白白暑假到巨石阵旅游。他们发现这些巨石高大耸峙,而且以一种富含魔力的方式排列着。他们面前有n块石头,明明给他们编号为1~n。而恰巧编号为i的石头高度也为i。他们随后惊奇地发现这些石头可以挪动,于是他们定义一个石头的排列为“魔阵”,当且仅当这个排列中最少有n-k个石头满足它所处的位置等于它的高度,即ai=i;
明明明明明白白白白白浪费了一天的时间来搬石头,但他还是想计算一下一共有几种“魔阵”。
输入
有多组测试样例。每行两个数n和k,4<=n<=1000 1<=k<=4
输出
每行一个答案,输出魔阵的种类数量。
样例输入
4 1
200 3
200 4
1000 4
样例输出
1
2646701
584811251
373086956251
分析:
很明显的错位排列题,由于k很小只有4,所以直接分类讨论一下就可以了,甚至暴力都可以完成。
k=1
只有一种,1,2,3,4........n,F[1]=1;
k=2
从n个数中选择2个,有C(n,2)种选法,选出的两个数交换一下,所以每种选法有1种情况,F[2]=F[1]+C(n,2);
位置 | 1 | 2 |
情况1(合法) | 2 | 1 |
情况2(重复) | 1 | 2 |
k=3
从n个数中选择3个,有C(n,3)种选法,选出的三个数有两种交换,所以每种选法有2种情况
F[3]=F[1]+F[2]+C(n,3)*2
位置 | 1 | 2 | 3 |
重复 | 1 | 2 | 3 |
重复 | 1 | 3 | 2 |
重复 | 2 | 1 |
3 |
合法 | 2 | 3 | 1 |
合法 | 3 | 1 | 2 |
重复 | 3 | 2 | 1 |
k=4
从n个数中选择4个,有C(n,3)种选法,选出的三个数有两种交换,所以每种选法有9种情况,F[4]=F[1]+F[2}+F[3]+C(n,4)*9
位置 | 1 | 2 | 3 | 4 |
1 | 2 | 1 | 4 | 3 |
2 | 2 | 3 | 4 | 1 |
3 | 2 | 4 | 1 | 3 |
4 | 3 | 2 | 4 | 1 |
5 | 3 | 1 | 2 | 4 |
6 | 3 | 1 | 4 | 2 |
7 | 4 | 1 | 2 | 3 |
8 | 4 | 3 | 1 | 2 |
9 | 4 | 3 | 2 | 1 |
#include<bits/stdc++.h>
using namespace std;
long long int n,k;
int main() {
while(~scanf("%lld %lld",&n,&k))
{
long long t=1;
if(k==1)
{
printf("1\n");
}
t+=n*(n-1)/2;
if(k==2)
{
printf("%lld\n",t);
}
t=t+n*(n-1)*(n-2)/3;
if(k==3)
{
printf("%lld\n",t);
}
t=t+n*(n-1)*(n-2)*(n-3)*3/8;
if(k==4)
{
printf("%lld\n",t);
}
}
return 0;
}
关于 long long int(64位长整型)的输出
1<<63 错误,由于1默认是int型,左移63位后就会溢出
1LL<<63 正确,先把1转换为long long 型,然后左移63位就不会溢出啦
long long t=(1LL<<63);
printf("%lld\n",t);
printf("%lld\n",1LL<<63);