zoukankan      html  css  js  c++  java
  • 【agc013d】Piling Up(动态规划)

    【agc013d】Piling Up(动态规划)

    题面

    atcoder
    洛谷
    (n)个球,颜色为黑白中的一种,初始时颜色任意。
    进行(m)次操作,每次操作都是先拿出一个求,再放进黑白各一个,再拿出一个球。
    求最终拿出球的序列的方案数。

    题解

    首先可以把操作看成每次拿出一个球把它染上任意一种颜色。
    (f[i][j])表示进行完前(i)次操作,还剩下(j)个黑球的方案数。
    拿出球的序列如果只从黑球的角度来看的话,可以看成一个(+1,-1)组成的折线。
    如果折线能够到达的最小值不为(0),那么我们可以通过平移把它移到(0)这个位置,并且平移过程中所有的操作序列所得到的结果串都是一样的。
    那么我们强制只在(0)位置计算答案,给状态额外加上一维,表示(j)是否到达过(0)
    这样子答案就是(sum f[m][j][1])了。

    #include<iostream>
    #include<cstdio>
    using namespace std;
    #define MOD 1000000007
    #define MAX 3030
    void add(int &x,int y){x+=y;if(x>=MOD)x-=MOD;}
    int n,m,ans,f[MAX][MAX][2];
    int main()
    {
    	scanf("%d%d",&n,&m);f[0][0][1]=1;
    	for(int i=1;i<=n;++i)f[0][i][0]=1;
    	for(int i=1;i<=m;++i)
    		for(int j=0;j<=n;++j)
    			for(int k=0;k<=1;++k)
    			{
    				if(j)add(f[i][j][k|(j==1)],f[i-1][j][k]),add(f[i][j-1][k|(j==1)],f[i-1][j][k]);
    				if(n-j)add(f[i][j+1][k],f[i-1][j][k]),add(f[i][j][k],f[i-1][j][k]);
    			}
    	for(int i=0;i<=n;++i)add(ans,f[m][i][1]);
    	printf("%d
    ",ans);return 0;
    }
    
  • 相关阅读:
    养生与健康
    vue + elementui 使用多选按钮实现单选功能
    生活小方
    和业务相关的工具函数
    vue + element ui开发过程中需要注意的几个点
    【转】webpack中关于source map的配置
    【转】移动前端手机输入法自带emoji表情字符处理
    webpack相关
    vue项目优化
    运维集群架构演变之美 【转】
  • 原文地址:https://www.cnblogs.com/cjyyb/p/10468305.html
Copyright © 2011-2022 走看看