1 条题解
-
0
自动搬运
来自洛谷,原作者为

Purified
None搬运于
2025-08-24 21:35:48,当前版本为作者最后更新于2017-07-11 20:33:16,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
###这绝对不是一道入门难度的题!
虽然我手贱写了入门。。。。
第一次写题解求轻喷
你会发现这道题改一下会变成这样
有一个长度为N-2的序列,你能进行M次操作
每次操作可以翻转其中的一个子序列(也可以不反转 浪费一次操作)
初始值全为0
求M次操作能获得的可能结果有多少种
然后就变成了求组合数的和
你会发现M次操作可以产生的0段1段的数量小于2*M+1
序列有N-3个空
插0~2*M次就可以了
注意除了2*M次 其他的组合数都是要*2的(你还有剩余操作可以把它整体翻过来嘛)
高精没优化也过了(数据并不是很强 我甚至不知道需不需要高精 但理论上讲是要的)
上代码
’‘’cpp
#include<bits/stdc++.h> #define MAXN 105 int ans[MAXN],f[MAXN]; void cauculate1(int a) {for(int i=0;i<MAXN;i++) f[i]*=a; for(int i=MAXN-1;i>=1;i--) {f[i-1]+=f[i]/10;f[i]%=10;} return;} void cauculate2(int a) {int flag=0; for(int i=0;i<MAXN;i++) {flag*=10;flag+=f[i]; f[i]=flag/a;flag%=a;} return;} void cauculate3(int k) { for(int i=MAXN-1;i>=1;i--) { ans[i]+=k*f[i]; ans[i-1]+=ans[i]/10; ans[i]%=10; } return; } void cmn(int n,int m) { f[MAXN-1]=1; for(int i=0;i<m;i++) cauculate1(n-i); for(int i=0;i<m;i++) cauculate2(1+i); return; } int main() { int op,l,i; scanf("%d%d",&l,&op); l=l-2; if(op==0) { printf("1"); return 0; } if(op>(l-1)/2) { f[104]=1; for(i=0;i<l;i++) cauculate1(2); for(i=0;i<MAXN;i++) if(f[i]) break; for(;i<MAXN;i++) printf("%d",f[i]); } else { for(i=1;i<2*op;i++) { cmn(l-1,i); cauculate3(2); memset(f,0,sizeof(f)); } cmn(l-1,2*op); cauculate3(1); memset(f,0,sizeof(f)); f[MAXN-1]=2; cauculate3(1); for(i=0;i<MAXN;i++) if(ans[i]) break; for(;i<MAXN;i++) printf("%d",ans[i]); } return 0; } ‘’‘
- 1
信息
- ID
- 1266
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者