思维递推题。
题目大意:以题目的那种形式列出来 问在N 的这些排列中有多少个K
一开始想的是把所有的式子列出来 然后看 1 - N 出现的次数的规律
后来发现就算求出来的话也无法递推出来。
其实换一种想法。想K这个数会出现多少次 不管别的数
那么把数看成N个点。
比如 K=2 N=5 (1 1 1 1 1 )在这之间插入若干斜杠隔开。组成不同的组合。
那么我们首先选一个K的长度 保证了K的出现。
那么有几种情况。这个K 的长度包含了端点还是没选端点。
当选择了端点的时候 其他位置只有N - K -1 个位置可以插入斜杠。 每个斜杠的位置可以选择放或者不放 所有就有 2 ^ ( n - k - 1) *2
没有选端点的时候 就有N-K-1 的位置 2^(n-k-2)*(n-k-1);
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #define mod 1000000007 #define LL __int64 using namespace std; LL pow_mod(LL a,LL i,LL n) { if(i==0)return 1%n; LL temp=pow_mod(a,i>>1,n); temp=temp*temp%n; if(i&1)temp=temp*a%n; return temp; } int main() { int k,n; int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&k); LL ans=pow_mod(2,n-k,mod); if(k>n) { printf("0 "); continue; } else if(k==n) { printf("1 "); continue; } else if(n-k==1) { printf("2 "); continue; } else if(n-k==2) { printf("5 "); continue; } else { ans=pow_mod(2,n-k-2,mod)*(n-k-1); ans%=mod; ans+=pow_mod(2,n-k,mod); ans%=mod; printf("%I64d ",ans); } } return 0; }