【题目】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;
 }