[背包DP][小技巧] LOJ#6089. 小 Y 的背包计数问题 && 51NOD 1597 有限背包计数问题
2017-07-06 20:31
246 查看
很妙的想法啊
体积小于m−−√的多重背包加个前缀和优化,大于m−−√的完全背包
具体看http://blog.csdn.net/u014609452/article/details/70477163
没有Manchery都快不会做题了……
体积小于m−−√的多重背包加个前缀和优化,大于m−−√的完全背包
具体看http://blog.csdn.net/u014609452/article/details/70477163
没有Manchery都快不会做题了……
#include <cstdio> #include <iostream> #include <algorithm> using namespace std; const int N=100010,M=330,P=23333333; int n,m; int f[2] ,tmp ; int g[M] ; #define F(x) (x<0?0:tmp[x]) inline void add(int &x,long long y){ (x+=y)%=P; } int main(){ scanf("%d",&n); m=sqrt(n); f[0][0]=1; int t=0; for(int i=1;i<=m;i++,t^=1){ for(int j=0;j<i;j++) tmp[j]=f[t][j]; for(int j=i;j<=n;j++) tmp[j]=(tmp[j-i]+f[t][j])%P; for(int j=0;j<=n;j++) f[t^1][j]=(1LL*f[t][j]+F(j-i)+P-F(j-(i+1)*i))%P; } g[1][m+1]=1; for(int i=0;i<=n;i++) tmp[i]=0; for(int i=1;i<=m;i++){ for(int j=1;j<=n;j++){ if(j+i<=n) add(g[i][j+i],g[i][j]); if(j+m+1<=n) add(g[i+1][j+m+1],g[i][j]); add(tmp[j],g[i][j]); } } tmp[0]=1; int ans=0; for(int i=0;i<=n;i++) add(ans,1LL*f[t][i]*tmp[n-i]%P); printf("%d\n",ans); return 0; }
相关文章推荐
- 51nod 1597 有限背包计数问题 dp
- 51nod 1597 有限背包计数问题[dp][阈值]
- [背包DP || 多项式] 51Nod 1597 有限背包计数问题
- [DP] 51Nod 1597 有限背包计数问题
- 51nod 1201[整数划分] 1259[整数划分V2] 1597 [有限背包计数问题]
- [DP]51 Nod 1597——有限背包计数问题
- 【背包+阈值优化】51Nod 1597 有限背包计数问题
- 51nod 1597 有限背包计数问题
- 51Nod-1597-有限背包计数问题
- 51nod1597 有限背包计数问题[DP][分类讨论][前缀和]
- 【51nod1597】【DP】有限背包计数问题
- 51Nod 有限背包计数问题 题解报告
- 1597 有限背包计数问题
- 51nod 多重背包问题 (dp)
- 51nod 1086 背包问题V2 (巧妙dp,二进制)
- [51nod1597] 有限背包计数问题
- 51nod 1085 背包问题<水过>
- UVA242 背包问题&紫书dp习题9-5
- DP&背包问题
- 51nod1597 有限背包计数问题