[NOIP2006]2^k进制数
做题时间:2021.02.03
问有多少个进制数满足:
- 至少有位;
- 转化为进制数之后最多有位。
- 除最后一位外,每一位都严格小于右边一位
3 7
36
动态规划 or 组合数学、高精度
#include<cstdio> #include<iomanip> #include<iostream> #include<cstring> using namespace std; const int N=205; const int M=1<<9; string C[M][M],p,t,ans; int a[N],b[N],c[N]; int w,k; inline int Swap(int &x,int &y){int t=x;x=y;y=t;} string Add(string sa,string sb)//高精度加法 { memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); memset(b,0,sizeof(c)); t=""; int lena=sa.size(); int lenb=sb.size(),lenc; for(int i=0;i<lena;i++) a[i+1]=sa[lena-i-1]-'0'; for(int i=0;i<lenb;i++) b[i+1]=sb[lenb-i-1]-'0'; int i=1,x=0; while(i<=lena||i<=lenb){ c[i]=a[i]+b[i]+x; x=c[i]/10; c[i]%=10; i++; } if(x) c[i]=x; else i--; lenc=i; for(int i=lenc;i>=1;i--) t+=(char)c[i]+'0'; return t; } int main() { scanf("%d%d",&k,&w); int ed=1<<k,sp=1<<w%k; C[0][0]="1"; for(int i=1;i<=ed;i++) C[i][0]=C[i][i]="1"; for(int i=2;i<=ed;i++){ for(int j=1;j<i;j++) C[i][j]=Add(C[i-1][j],C[i-1][j-1]);//预处理组合数 } //这里其实可以将k整除w和k不整除w两种情况写在一起 for(int i=2;i<=w/k;i++){ if(i>ed-1) break; ans=Add(ans,C[ed-1][i]);//累加 } for(int i=1;i<=sp-1;i++){ if(w/k>ed-i-1) break; ans=Add(ans,C[ed-i-1][w/k]);//累加 } int len=ans.size(); for(int i=0;i<len;i++) printf("%c",ans[i]); return 0; }
本文作者:lxzy
本文链接:https://www.cnblogs.com/Unlimited-Chan/p/14368051.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步