POJ 1037 (计数 + DP) 一个美妙的栅栏
这道题总算勉勉强强看懂了,DP和计数都很不好想
DP部分:
称i根木棒的合法方案集合为S(i),第二根木棒比第一根长的方案称作UP方案,反之叫做DOWN方案
C[i][k][DOWN] 是S(i)中以第k短(而不是长度为k)的木棒打头的DOWN方案数。
假设S(i)中第一根木棒长为x,那么构成合法的方案数有两类:
- S(i - 1)中第一根木棒比x长的DOWN方案
- S(i - 1)中第一根木棒比x短的UP方案
有如下递推关系:
C[i][k][UP] = ∑ C[i-1][M][DOWN]
M = k ... i -1
C[i][k][DOWN] = ∑ C[i-1][N][UP]
N = 1… k-1
举个例子:
比如四根木棒,假设第一根木棒长度为2,在剩下的1 3 4中,比2长的3和4分别是S(3)中第2和第3短的。(要和C所定义的状态相对应)
所以上式的M和N的范围就是这样的
总的方案数就是:Sum{ C[n][k][DOWN] + C[n][k][UP] } k = 1.. n
计数部分:
扔掉这个题,考虑一下这个问题:
1 2 3 4全排列,求字典序的第10个
首先假设第一个数是1,那么后面有3! = 6 < 10种排列情况,所以打头的不是1。 继续假设是2,后面三个数也有6种排列情况, 6 + 6 ≥ 10,所以第一个数确定是2,此时跳过了第一个数为1的6种情况。
继续假设第二个数是1,后面有2! = 2种情况, 2 + 6 < 10,所以假设第二个数是3(注意2已经在第一个数中用过了),依旧是有2种情况, 8 + 2 ≥ 10,第二个数确定是3,跳过了10种情况。
后面因为10 ≥ 10,所以第三第四个数分别是1 4
所求的排列就是2 3 1 4
回到这个题上来:
前面已经求得了i个数中第k小打头的方案数,所以我们也完全可以模拟上面的思维过程来求解。
微调:以第i短的木棒作第k根时,有UP和DOWN两类方案,先用DOWN的方案数和C比较
//#define LOCAL
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std; const int maxn = ;
const int UP = ;
const int DOWN = ;
long long C[maxn][maxn][]; void Init(int n)
{
memset(C, , sizeof(C));
C[][][UP] = C[][][DOWN] = ;
for(int i = ; i <= n; ++i)
for(int k = ; k <= i; ++k)
{
for(int M = k; M < i; ++M)
C[i][k][UP] += C[i - ][M][DOWN];
for(int N = ; N <= k - ; ++N)
C[i][k][DOWN] += C[i - ][N][UP];
}
} void Print(int n, long long c)
{
long long skipped = ;
int seq[maxn], used[maxn];
memset(used, , sizeof(used));
for(int i = ; i <= n; ++i)
{
long long oldVal = skipped;
int k, No = ;
for(k = ; k <= n; ++k)
{
oldVal = skipped;
if(!used[k])
{
++No;
if(i == )
skipped += C[n][No][UP] + C[n][No][DOWN];
else
{
if(k > seq[i - ] && (i == || seq[i - ] > seq[i - ]))
skipped += C[n - i + ][No][DOWN];
else if(k < seq[i - ] && (i == || seq[i - ] < seq[i - ]))
skipped += C[n - i + ][No][UP];
}
if(skipped >= c)
break;
}
}
used[k] = ;
seq[i] = k;
skipped = oldVal;
} for(int i = ; i < n; ++i) printf("%d ", seq[i]);
printf("%d\n", seq[n]);
} int main(void)
{
#ifdef LOCAL
freopen("1037in.txt", "r", stdin);
#endif int T, n;
long long c;
Init();
scanf("%d", &T);
while(T--)
{
scanf("%d %lld", &n, &c);
Print(n, c);
}
return ;
}
代码君
POJ 1037 (计数 + DP) 一个美妙的栅栏的更多相关文章
- poj 1037 三维dp
A decorative fence Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 7221 Accepted: 272 ...
- POJ 2229 计数DP
dp[i]代表是数字i的最多组合数如果i是一个奇数,i的任意一个组合都包含1,所以dp[i] = dp[i-1] 如果i是一个偶数,分两种情况讨论,一种是序列中包含1,因此dp[i]=dp[i-1]一 ...
- CodeForces 176B Word Cut (计数DP)
Word Cut Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u Submit St ...
- [DP之计数DP]
其实说实在 我在写这篇博客的时候 才刚刚草了一道这样类型的题 之前几乎没有接触过 接触过也是平时比赛的 没有系统的做过 可以说0基础 我所理解的计数dp就是想办法去达到它要的目的 而且一定要非常劲非常 ...
- HDU 6377 度度熊看球赛 (计数DP)
度度熊看球赛 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Subm ...
- 计数dp
计数dp 计数类的$dp$没做过几个,所以之前都放到"思维"标签下了,后来发现原来这属于一类问题啊...搬过来了. 管道取珠:https://www.lydsy.com/Judge ...
- 【AtCoder】AGC022 F - Leftmost Ball 计数DP
[题目]F - Leftmost Ball [题意]给定n种颜色的球各k个,每次以任意顺序排列所有球并将每种颜色最左端的球染成颜色0,求有多少种不同的颜色排列.n,k<=2000. [算法]计数 ...
- 【BZOJ】4559: [JLoi2016]成绩比较 计数DP+排列组合+拉格朗日插值
[题意]n位同学(其中一位是B神),m门必修课,每门必修课的分数是[1,Ui].B神碾压了k位同学(所有课分数<=B神),且第x门课有rx-1位同学的分数高于B神,求满足条件的分数情况数.当有一 ...
- [ZJOI2010]排列计数 (组合计数/dp)
[ZJOI2010]排列计数 题目描述 称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有 ...
随机推荐
- CSS自定义文件上传按钮
今天一同事问我文件上传按钮的问题,情况是这样的,他页面上有3个按钮,分为左中右三个,左边的位按钮甲,右边的位按钮乙,而中间的就是个文件选择按钮,情况大概是这个样子的: 两边的按钮都有了样式,但中间的选 ...
- 8086CPU各寄存器的用途
8086 有14个16位寄存器,这14个寄存器按其用途可分为(1)通用寄存器.(2)指令指针.(3)标志寄存器和(4)段寄存器等4类. 1.通用寄存器有8个, 又可以分成2组,一组是数据寄存器(4个) ...
- android 关于Location of the Android SDK has not been setup in the preferences的解决方法
今天在部署android开发环境的时候,每次打开eclipse的时候点击AVD Manager的按钮就会弹出Location of the Android SDK has not been setup ...
- Http Url Get请求方式需要对中文参数进行编码
public static void main(String[] args) { try { String mytext = java.net.URLEncoder.encode("上海南站 ...
- Sqli-labs less 26
Less-26 TIPS:本关可能有的朋友在windows下无法使用一些特殊的字符代替空格,此处是因为apache的解析的问题,这里请更换到linux平台下. 本关结合25关,将空格,or,and,/ ...
- 斌哥的 Docker 进阶指南
过去的一年中,关于 Docker 的话题从未断过,而如今,从尝试 Docker 到最终决定使用 Docker 的转化率依然在逐步升高,关于 Docker 的讨论更是有增无减.另一方面,大家的注意力也渐 ...
- 为什么主流网站无法捕获 XSS 漏洞?
二十多年来,跨站脚本(简称 XSS)漏洞一直是主流网站的心头之痛.为什么过了这么久,这些网站还是对此类漏洞束手无策呢? 对于最近 eBay 网站曝出的跨站脚本漏洞,你有什么想法?为什么会出现这样的漏网 ...
- NDK 编译可执行程序
以Hello Android工程为例. 建立好工程hello-a,在jni目录下创建文件hello-a.c,文件内容如下.(注意是jni目录,使用src目录编译会出错) #include <st ...
- 2013 ACM/ICPC Asia Regional Online —— Warmup
1003 Rotation Lock Puzzle 找出每一圈中的最大值即可 代码如下: #include<iostream> #include<stdio.h> #inclu ...
- volatile 关键字的复习
今天早上看何登成的微博(http://hedengcheng.com/?p=725) 对volatile 关键字语意进行了深入分析. 看完之后,用自己的话总结如下: 1.c/c++ volatile中 ...