常规思路:n位二进制数的总个数C(n-1,0) + C(n-1,1) + C(n-1,2) +.....+C(n-1,n-1) = 2^(n-1)
其中C(n-1,1) 是组合
每位的第一位必须是1, 所以先把这个1算进去.
int total = 0; //总数初始化为0
total += 2^(n-1); //把上在讲的那种情况的1先算进来
然后后面的1可以这样算:
C(n-1,0)*0 + C(n-1,1)*1 + C*(n-1,2)*2 +.....+C*(n-1,n-1) * (n-1)
总量就求出来了
AC代码:
//Problem:hdu2502
//Data:2011-11-02
#include <iostream>
using namespace std;
__int64 combination(int n, int m)
{
//求组合数的函数,要用__int64,不然溢出
//这程序很弱,只能处理n较小的情况
if(m > n/2)
m = n-m;
__int64 resulT = 1;
int tempM = m;
int tempN = n;
while(tempM--)
{
resulT *= tempN--;
}
m++;
while(--m)
{
resulT /= m;
}
return resulT;
}
int pow(int x)
{
//求2^x
int ans = 1;
while(x--)
{
ans *= 2;
}
return ans;
}
int main()
{
int n;
cin >> n;
while(n--)
{
int input;
cin >> input;
//===========first step==============
int total = 0;
total += pow(input-1);
//==========second step=============
for(int i=0; i<=input-1; i++)
{
total += combination(input-1, i) * i;
}
cout << total << endl;
}
return 0;
}
下面还有一个很逆天的程序,是在此题的Discuss处看到的,很不解
公式怎么来的不太清楚。
表示还是很菜啊~~~~
#include<stdio.h>
int main()
{
int n,t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
printf("%d\n",(1<<(n-1))+(n-1)*(1<<(n-2)));
}
return 0;
}