HDU4248【DP】
来源:互联网 发布:javascript 循环 编辑:程序博客网 时间:2024/05/21 20:29
题意:
有n种石头,每种石头有a[i]个,然后让你去组合,问有多少种组合;
思路:
这种题,排列组合知识一上,非常麻烦,已经搞了好几题,看似就是排列组合的姿势,然而最终都是一种递推,也就是DP,而且比较明显的是,基本上这种数的数量级就在100/1000这样。DP来还是很有道理的;
本题:
dp[i][j] 表示前i堆石子构成长度为j的串的方案数;
k代表第 i 堆对于j的使用量,num是当前构成的长度;
然后状态转移就是:dp[i,j]+=dp[i-1,j-k]*C[ k ,num ];
预处理组合数,利用组合的性质:C(n+1,i)=C(n,i)+C(n,i-1);
最后把所有长度的可能性的种类加起来。
#include<stdio.h>#include<queue>#include<string.h>#include<iostream>#include<algorithm>using namespace std;typedef long long LL;const int INF=0x3f3f3f3f;//dp[i][j] 表示前i堆石子构成长度为j的串的方案数;const int N=1e4+10;const LL mod=1e9+7;//int num[N];int num;LL dp[110][N];LL C[N][110];void init(){ C[0][0]=1; for(int i=1;i<N;i++) for(int j=0;j<=100;j++) { if(!j) C[i][j]=C[i-1][j]; else C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod; }}int main(){ init(); int cas=1; int n; while(~scanf("%d",&n)) { memset(dp,0,sizeof(dp)); dp[0][0]=1; int sum=0; for(int i=1;i<=n;i++) { scanf("%d",&num); sum+=num; for(int k=0;k<=num;k++) for(int j=k;j<=sum;j++) dp[i][j]=(dp[i][j]+(dp[i-1][j-k]*C[j][k]%mod))%mod; } LL ans=0; for(int i=1;i<=sum;i++) ans=(ans+dp[n][i])%mod; printf("Case %d: ",cas++); printf("%lld\n",ans); } return 0;}
0 0
- HDU4248【DP】
- hdu4248 组合数学+DP
- hdu4248 A Famous Stone Collector
- #HDU4248#A Famous Stone Collector(组合数)
- dp
- dp
- dp
- 【DP】
- dp
- dp
- DP
- DP
- DP
- DP
- DP
- dp
- DP
- dp
- SDN中的wiresharrk(2)
- MCS-51单片机的定时器/计数器概念 寄存器关系图
- 第十五天
- NKOI 3081 追赶游戏
- webview,js和android交互
- HDU4248【DP】
- 互联网公司面试问题总结之SSH框架
- 【一步步学OpenGL 16】 -《纹理贴图》
- python数据集标签小脚本,修改目标图片坐标格式,更改标签
- Fragment的使用小结(二)
- 互联网公司面试问题总结之虚拟机JVM
- 持续更新
- A+B problem
- TCP连接的建立与中止(非原创)