【题解】At2370 Piling Up
【题解】At2370 Piling Up
\\
正在进行i项操作并且此时黑球剩下j个,黑球[0/1]数量曾经到过0
\\
为什么加第二位,判重。怎么想到的?
\]
非常神仙了。现在我做题基本上就是改编戏说了...自己是做不出来的,不管是只是层面还是思维层面的高度都不够。
那就一题一题地吸收吧。
其实问这样的\(dp\)设计是如何想到的,都是人们看清楚了方案重合的本【题解】At2370 Piling Up质是什么,然后就针对这个本质设计来的...
感觉这种设\(0/1\)有一定的代表性,图文解释一下


假设蓝色的线是黑球的数量关于\(t\)的变化关系函数,可以知道同样形状的线拿出来的样子是一样的,但是如果直接\(dp(i,j)\)没有\(0\ / \ 1\)就会把图中四根线代表的颜色序列当做不一样的,这样就重复了。
有什么办法可以避免呢?我们可以发现,同样的走的曲线一定是将整个坐标系排满了,意思是排到无法再加入新的同样走的曲线进去了,如果要无法再加曲线,那么一定有一根曲线曾经到过坐标轴(黑线)。这是解决重复的关键,也是问题的本质。
也就是说,我们标识一个\(dp(i,j)\)是否曾经到过底部,就可以防止这样的重复了。
你肯定发现问题了,一定存在这样的排颜色方案使得黑球数量从没有为0。不过我们钦定一条在\(i=0\)处变为\(0\)的曲线就好了。

考虑怎么转移,分类讨论:
- 白白
- 黑黑
- 白黑
- 黑白
转移很好转移(也没有好吗!这种转移对我来说就相当于做第二道题目了!就是那种神仙学长都觉得很显然但是我要折寿地去推导啊啊啊啊啊啊啊QAQQAQ)。
上抄的代码,wk1自己写的(不对),wk2是题解
#include<bits/stdc++.h>
using namespace std;typedef long long ll;
#define DRP(t,a,b) for(register int t=(a),edd=(b);t>=edd;--t)
#define RP(t,a,b) for(register int t=(a),edd=(b);t<=edd;++t)
#define ERP(t,a) for(register int t=head[a];t;t=e[t].nx)
#define midd register int mid=(l+r)>>1
#define TMP template < class ccf >
#define lef l,mid,pos<<1
#define rgt mid+1,r,pos<<1|1
#define pushup(pos) (seg[pos]=seg[pos<<1]+seg[pos<<1|1])
TMP inline ccf qr(ccf b){
register char c=getchar();register int q=1;register ccf x=0;
while(c<48||c>57)q=c==45?-1:q,c=getchar();
while(c>=48&&c<=57)x=x*10+c-48,c=getchar();
return q==-1?-x:x;}
TMP inline ccf Max(ccf a,ccf b){return a<b?b:a;}
TMP inline ccf Min(ccf a,ccf b){return a<b?a:b;}
TMP inline ccf Max(ccf a,ccf b,ccf c){return Max(a,Max(b,c));}
TMP inline ccf Min(ccf a,ccf b,ccf c){return Min(a,Min(b,c));}
TMP inline ccf READ(ccf* _arr,int _n){RP(t,1,_n)_arr[t]=qr((ccf)1);}
//----------------------template&IO---------------------------
const int maxn=3e3+15;
const ll mod=1e9+7;
ll dp[maxn][maxn][2];
ll ans;
#define md(x) ((x)%mod)
#define add(x,y) ((x)=md((x)+(y)))
int n,m;
inline void wk(){
dp[1][0][1]=dp[1][1][1]=1;
RP(t,1,n) dp[1][t][0]=2;
RP(t,1,m){
RP(i,0,n){
//取两个白
if(i<n){
if(i){
dp[t+1][i+1][0]=md(dp[t+1][i+1][0]+dp[t][i][0]);
dp[t+1][i+1][1]=md(dp[t+1][i+1][1]+dp[t][i][1]);
}
else dp[t+1][i+1][1]=md(dp[t+1][i+1][1]+dp[t][i][0]+dp[t][i][1]);
}
//取两个黑色
if(i){
if(i-1){
dp[t+1][i-1][0]=md(dp[t+1][i-1][0]+dp[t][i][0]);
dp[t+1][i-1][1]=md(dp[t+1][i-1][1]+dp[t][i][1]);
}
else dp[t+1][i-1][1]=md(dp[t+1][i-1][1]+dp[t][i][0]+dp[t][i][1]);
}
//一黑一白
if(i){
dp[t+1][i][0]=md(dp[t+1][i][0]+(dp[t][i][0]<<1));
dp[t+1][i][1]=md(dp[t+1][i][1]+(dp[t][i][1]<<1));
}
else dp[t+1][i][1]=md(dp[t+1][i][1]+dp[t][i][0]);
}
}
}
inline void wk2(){
dp[1][0][1]=1;
RP(t,1,n) dp[1][t][0]=1;
RP(t,1,m){
RP(i,0,n){
if(i){
add(dp[t+1][i-1][1],dp[t][i][1]);
add(dp[t+1][i][1],dp[t][i][1]);
if(i==1) add(dp[t+1][i-1][1],dp[t][i][0]),add(dp[t+1][i][1],dp[t][i][0]);
else add(dp[t+1][i-1][0],dp[t][i][0]),add(dp[t+1][i][0],dp[t][i][0]);
}
if(i<n){
add(dp[t+1][i+1][0],dp[t][i][0]);
add(dp[t+1][i+1][1],dp[t][i][1]);
add(dp[t+1][i][0],dp[t][i][0]);
add(dp[t+1][i][1],dp[t][i][1]);
}
}
}
}
int main(){
n=qr(1);m=qr(1);
wk2();
RP(t,0,n) ans=md(ans+dp[m+1][t][1]);
cout<<ans<<endl;
return 0;
}
【题解】At2370 Piling Up的更多相关文章
- AT2370 Piling Up
https://www.luogu.org/jump/atcoder/2370 题解 答案不是\(2^{2m}\)因为每轮的第一次取球可能会不够. 我们可以设\(dp[i][j]\)表示到了第\(i\ ...
- 【题解】Counting D-sets(容斥+欧拉定理)
[题解]Counting D-sets(容斥+欧拉定理) 没时间写先咕咕咕. vjCodeChef - CNTDSETS 就是容斥,只是难了一二三四五\(\dots \inf\)点 题目大意: 给定你 ...
- 一句话题解&&总结
CF79D Password: 差分.两点取反,本质是匹配!最短路+状压DP 取反是套路,匹配是发现可以把操作进行目的化和阶段化,从而第二次转化问题. 且匹配不会影响别的位置答案 sequence 计 ...
- AtCoder Grand Contest 013D: Piling Up 题解
题意简化: [luogu] Piling Up 一开始有n个颜色为黑白的球,但不知道黑白色分别有多少,m次操作,每次先拿出一个球,再放入黑白球各一个,再拿出一个球,最后拿出的球按顺序排列会形成一个颜色 ...
- 【agc013d】Piling Up(动态规划)
[agc013d]Piling Up(动态规划) 题面 atcoder 洛谷 有\(n\)个球,颜色为黑白中的一种,初始时颜色任意. 进行\(m\)次操作,每次操作都是先拿出一个求,再放进黑白各一个, ...
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
随机推荐
- vue.js移动端app实战1
本系列将会用vue.js2制作一个移动端的webapp单页面,页面不多,大概在7,8个左右,不过麻雀虽小,五脏俱全,常用的效果如轮播图,下拉刷新,上拉加载,图片懒加载都会用到.css方面也会有一些描述 ...
- Java开发笔记(一百零三)线程间的通信方式
前面介绍了多线程并发之时的资源抢占情况,以及利用同步.加锁.信号量等机制解决资源冲突问题,不过这些机制只适合同一资源的共享分配,并未涉及到某件事由的前因后果.日常生活中,经常存在两个前后关联的事务,像 ...
- 【iOS】Frame和Bounds的区别以及获取绝对坐标的办法
终于搞清楚了,UIView中的frame获取的是相对于所在ParentView的坐标,而bounds则是指UIView本身的坐标.比如下图(假设A是屏幕): View B的Frame坐标是指相对于Vi ...
- django admin页面样式丢失问题
wamp 配置django admin页面样式丢失问题 第一种方法:在apache配置文件httpd.conf中加入如下代码:Alias /static "E:\Python27\Lib\s ...
- Python批量复制和重命名文件
Python批量复制和重命名文件 示例代码 #! /usr/bin/env python # coding=utf-8 import os import shutil import time impo ...
- springboot + mybatis配置多数据源示例
转:http://www.jb51.net/article/107223.htm 在实际开发中,我们一个项目可能会用到多个数据库,通常一个数据库对应一个数据源. 代码结构: 简要原理: 1)Datab ...
- Python标准库:1. 介绍
标准库包括了几种不同类型的库. 首先是那些核心语言的数据类型库,比方数字和列表相关的库.在核心语言手冊里仅仅是描写叙述数字和列表的编写方式,以及它的排列,而未定义它的语义. 换一句话说,核心语言手冊仅 ...
- prop()方法和attr()方法以及区别
prop()方法: prop() 方法设置或返回被选元素的属性和值. 当该方法用于返回属性值时,则返回第一个匹配元素的值. 当该方法用于设置属性值时,则为匹配元素集合设置一个或多个属性/值对. 注意: ...
- CPU_CState_PState and then ACPI on Wiki
http://wenku.baidu.com/link?url=eHbdT4EjdJx3dsQETGUIL8q1K3_EyuzGLWT0G103AEca0vs0gHR_v_3c0oaUL2gbkrr8 ...
- java 匿名类和匿名方法
package com.test; interface product{ int getPrice(); } public class News { /** * @param args */ publ ...