博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[P1329] 数列
阅读量:4520 次
发布时间:2019-06-08

本文共 1212 字,大约阅读时间需要 4 分钟。

设F[i,j]为长度为i是,前缀和为j的方案数。

【转移】

F[i,j] => F[i+1,j+i]
F[i,j] => F[i+1,j-i]
【原理】
由于A[0]=0,所以有A[1]=-1或A[1]=1 。又要满足|A[i]-A[i-1]|=1,所以 这样思考:
从F[i,*]转移到F[i+1,*]时,假象在长度为i的A序列后添一个A[i]+1 或A[i]-1。我们惊奇地发现,这样是做不出来的。

怎么办呢???

看过题解后我们发现,上述方法不适用的原因是A[n]情况太多了。不方便。 与之相反的是,A[0]={0},A[1]={1,-1}的情况就很少 。我们何不在A[0]和A[1]中插入一个数构成新序列呢 ??

举个栗子:当A[1]为1时,在其中插入一个1,为了满足 |A[i]-A[i-1]|=1 的性质,不得不当原来的A[1~i]都加上一个1或-1,即转移到了F[i+1,j+i-1+1] 和 F[i+1,j-i+1-1] 。

还有三种情况,道理相同就不再赘述了。

【输出答案】搜索,利用F数组剪纸就好。

我是真菜啊 。

#include 
#include
#include
#include
using namespace std;const int N=110;const int M=20000;int n,sum,a[N];long long tot,f[N][M+1];void print(int x) { if(x==1 && !sum) { printf("0"); for(int k=0,i=n; i>1; --i) { k+=a[i]; printf(" %d",k); } printf("\n"); if(--tot==0) exit(0); } if(f[x][sum<0?sum+M:sum]==0) return; a[x]=-1; sum+=(x-1); print(x-1); sum-=(x-1); a[x]= 1; sum-=(x-1); print(x-1); sum+=(x-1);}int main() { f[1][0]=1; scanf("%d%d",&n,&sum); for(int i=1,j,k; i
100) tot=100; print(n); return 0;}

转载于:https://www.cnblogs.com/nosta/p/10197940.html

你可能感兴趣的文章
jacob 给word加印的功能
查看>>
利用for循环来实现全选
查看>>
在Hbuilder中的项目传到github的步骤
查看>>
高级DirectDraw 分类: VC++ D...
查看>>
Vue2.0的动画效果
查看>>
记录一次nginx的upstream的配置信息
查看>>
Bug搬运工-CSCvm33229:Environment summary not available on COS APs
查看>>
じ守望者┱ o
查看>>
底层驱动框架1
查看>>
jquery formcheck.js
查看>>
51nod 1251 Fox序列的数量 (容斥)
查看>>
centos7安装Lnmp(Linux+Nginx+MySql+Php+phpMyAdmin+Apache)
查看>>
iOS内存警告浅析
查看>>
Python入门---[第二篇]基础语法
查看>>
Swift---Swift5基本语法
查看>>
分析Ajax请求并抓取今日头条街拍美图
查看>>
[bzoj1452][JSOI2009]Count(树状数组)
查看>>
C/C++(指针数组)
查看>>
数据库的三大范式
查看>>
结对第二次—文献摘要热词统计及进阶需求
查看>>