【题目】http://acm.hdu.edu.cn/showproblem.php?pid=4602
【报告】
直接贴上标程解题报告:(虽然有些纠结,试一下就弄通了。。)
Problem C. Partition
我们可以特判出n<= k的情况。
对于1<= k,我们可以等效为n个点排成一列,并取出其中的连续k个点。下面分两种情况考虑:
第一种情况,被选出的不包含端点,那么有(n–k−1)种情况完成上述操作,剩下未被圈的点之间还有(n–k−2)个位置,可以在每个位置断开,所以共2^(n−k−2) ∗(n−k−1)种方法。
第二种情况,即被选出的包含端点,那么有2种情况,并且剩余共(n–k−1)个位置,所以共2∗2^(n–k−1)种方法。
总计2∗2^(n–k−1) +2^(n–k−2) ∗(n–k−1)=(n–k+3)* 2^(n–k−2)。
注意一下本题需要用long long,还要特殊处理n
【程序】
// Task: HDOJ 4602 Partition
// Designer: Rsky 2013/08/11
#include
#include
#include
#include
using namespace std;
const long long MOD = 1000000007ll;
long long solve(long long n,long long k)
{
if(n
if(n==k) return 1;
long long ans=n-k+3;
long long tmp=2;
k=n-k-2;
if(k==-1) return ans/2;
while(k){
if(k%2){
ans=(ans*tmp)%MOD;
}
tmp=(tmp*tmp)%MOD;
k/=2;
}
return ans;
}
int main()
{
int t;
cin >> t;
while (t--)
{
long long n,k;
cin >> n >> k;
cout << solve(n,k) << endl;
// scanf("%lld%lld",&n,&k);
// printf("%lld\n",solve(n,k));
}
return 0;
}