bzoj1037(dp 1A)
2016-08-19 10:30
127 查看
这道题做的痛快!加油!
因为发现三维没法表示状态,没法处理
所以,发现数据范围,允许我们再加一维。所以用四维进行表示
Dp[i][j][k1][k2]表示i个男孩,j个女孩,从后往前,男孩最多比女孩多k1个,女孩最多比男孩多k2个的方案数(实际上,我们在后面再加一个人,影响区间的男女之差,只会影响到之前那个区间的后缀,因为,前面的区间已经固定了,是不会影响到的)。
转移就分,这一位是男孩还是女孩来进行转移。
注意,当上一个的女孩最多比男孩多的个数(即k2)为0,且这一位是男孩,答案要加上上一位k2为0的方案(再来一个男孩,还是最多为0个)和上一位k2为1的方案(本来女孩差是1,来一个男孩,差就是0了)
这题唯一不算特别清楚的是初始边界问题,感觉很乱,就写了个暴力程序(在下面),试了几组数据,没什么问题,就直接交了
暴力程序,用的next_permutation
因为发现三维没法表示状态,没法处理
所以,发现数据范围,允许我们再加一维。所以用四维进行表示
Dp[i][j][k1][k2]表示i个男孩,j个女孩,从后往前,男孩最多比女孩多k1个,女孩最多比男孩多k2个的方案数(实际上,我们在后面再加一个人,影响区间的男女之差,只会影响到之前那个区间的后缀,因为,前面的区间已经固定了,是不会影响到的)。
转移就分,这一位是男孩还是女孩来进行转移。
注意,当上一个的女孩最多比男孩多的个数(即k2)为0,且这一位是男孩,答案要加上上一位k2为0的方案(再来一个男孩,还是最多为0个)和上一位k2为1的方案(本来女孩差是1,来一个男孩,差就是0了)
这题唯一不算特别清楚的是初始边界问题,感觉很乱,就写了个暴力程序(在下面),试了几组数据,没什么问题,就直接交了
#include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<algorithm> #include<iostream> #define debug(x) cout<<#x<<"="<<x<<endl using namespace std; typedef long long ll; const int mod=12345678; int n,m,k; ll f[152][152][22][22]; void MOD(ll &x) { if (x>=mod) x-=mod; } int main() { scanf("%d%d%d",&n,&m,&k); f[0][0][0][0]=1; f[1][0][1][0]=1; f[0][1][0][1]=1; for (int i=0;i<=n;i++) for (int j=0;j<=m;j++) { if (i==0&&j==0) continue; for (int ki=0;ki<=k;ki++) for (int kj=0;kj<=k;kj++) if (f[i][j][ki][kj]==0) { if (i>0&&ki>0) { f[i][j][ki][kj]+=f[i-1][j][ki-1][kj+1],MOD(f[i][j][ki][kj]); if (kj==0) f[i][j][ki][kj]+=f[i-1][j][ki-1][0],MOD(f[i][j][ki][kj]); } if (j>0&&kj>0) { f[i][j][ki][kj]+=f[i][j-1][ki+1][kj-1],MOD(f[i][j][ki][kj]); if (ki==0) f[i][j][ki][kj]+=f[i][j-1][0][kj-1],MOD(f[i][j][ki][kj]); } } } ll ans=0; for (int i=0;i<=k;i++) for (int j=0;j<=k;j++) ans+=f [m][i][j],MOD(ans); printf("%lld",ans); return 0; }
暴力程序,用的next_permutation
#include<cstdio> #include<cstdlib> #include<cmath> #include<algorithm> using namespace std; int a[10005]; int main() { int n,m,k; scanf("%d%d%d",&n,&m,&k); int len=0; for (int i=1;i<=n;i++) a[++len]=0; for (int i=1;i<=m;i++) a[++len]=1; int ans=0; do { int boy=0,girl=0; bool o=true; for (int i=1;i<=len;i++) { if (a[i]==0) boy++,girl--; else boy--,girl++; boy=max(0,boy); girl=max(0,girl); if (boy>k||girl>k) {o=false;break;} } if (o) ans++; }while (next_permutation(a+1,a+len+1)); printf("%d",ans); return 0; }
相关文章推荐
- BZOJ 1037: [ZJOI2008]生日聚会Party [序列DP]
- 【bzoj 1037】生日聚会Party(DP)
- BZOJ 1037: [ZJOI2008]生日聚会Party( dp )
- BZOJ 1037: [ZJOI2008]生日聚会Party DP
- bzoj1037: [ZJOI2008]生日聚会Party(dp)
- [BZOJ1037][ZJOI2008]生日聚会Party dp
- bzoj 1037: [ZJOI2008]生日聚会Party (DP)
- [bzoj1037][ZJOI2008]生日聚会Party dp
- BZOJ 1037: [ZJOI2008]生日聚会Party(区间dp)
- HYSBZ/BZOJ 1037 [ZJOI2008] 生日聚会Party - dp
- BZOJ.1037.[ZJOI2008]生日聚会Party(DP)
- bzoj 1037: [ZJOI2008]生日聚会Party (dp)
- BZOJ1037 DP
- bzoj 1037: [ZJOI2008]生日聚会Party dp
- bzoj1037: [ZJOI2008]生日聚会Party DP
- bzoj 1037 [ZJOI2008]生日聚会Party(DP)
- 【BZOJ1037】【codevs1410】生日聚会,DP
- [BZOJ1037]ZJOI2008生日聚会|DP
- [bzoj1037][DP]生日聚会party
- BZOJ 1037 [ZJOI2008]生日聚会Party(单调DP)