这道题总算勉勉强强看懂了,DP和计数都很不好想

DP部分:

称i根木棒的合法方案集合为S(i),第二根木棒比第一根长的方案称作UP方案,反之叫做DOWN方案

C[i][k][DOWN] 是S(i)中以第k短(而不是长度为k)的木棒打头的DOWN方案数。

假设S(i)中第一根木棒长为x,那么构成合法的方案数有两类:

  1. S(i - 1)中第一根木棒比x长的DOWN方案
  2. 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) 一个美妙的栅栏的更多相关文章

  1. poj 1037 三维dp

    A decorative fence Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7221   Accepted: 272 ...

  2. POJ 2229 计数DP

    dp[i]代表是数字i的最多组合数如果i是一个奇数,i的任意一个组合都包含1,所以dp[i] = dp[i-1] 如果i是一个偶数,分两种情况讨论,一种是序列中包含1,因此dp[i]=dp[i-1]一 ...

  3. CodeForces 176B Word Cut (计数DP)

    Word Cut Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit St ...

  4. [DP之计数DP]

    其实说实在 我在写这篇博客的时候 才刚刚草了一道这样类型的题 之前几乎没有接触过 接触过也是平时比赛的 没有系统的做过 可以说0基础 我所理解的计数dp就是想办法去达到它要的目的 而且一定要非常劲非常 ...

  5. HDU 6377 度度熊看球赛 (计数DP)

    度度熊看球赛 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Subm ...

  6. 计数dp

    计数dp 计数类的$dp$没做过几个,所以之前都放到"思维"标签下了,后来发现原来这属于一类问题啊...搬过来了. 管道取珠:https://www.lydsy.com/Judge ...

  7. 【AtCoder】AGC022 F - Leftmost Ball 计数DP

    [题目]F - Leftmost Ball [题意]给定n种颜色的球各k个,每次以任意顺序排列所有球并将每种颜色最左端的球染成颜色0,求有多少种不同的颜色排列.n,k<=2000. [算法]计数 ...

  8. 【BZOJ】4559: [JLoi2016]成绩比较 计数DP+排列组合+拉格朗日插值

    [题意]n位同学(其中一位是B神),m门必修课,每门必修课的分数是[1,Ui].B神碾压了k位同学(所有课分数<=B神),且第x门课有rx-1位同学的分数高于B神,求满足条件的分数情况数.当有一 ...

  9. [ZJOI2010]排列计数 (组合计数/dp)

    [ZJOI2010]排列计数 题目描述 称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有 ...

随机推荐

  1. CSS自定义文件上传按钮

    今天一同事问我文件上传按钮的问题,情况是这样的,他页面上有3个按钮,分为左中右三个,左边的位按钮甲,右边的位按钮乙,而中间的就是个文件选择按钮,情况大概是这个样子的: 两边的按钮都有了样式,但中间的选 ...

  2. 8086CPU各寄存器的用途

    8086 有14个16位寄存器,这14个寄存器按其用途可分为(1)通用寄存器.(2)指令指针.(3)标志寄存器和(4)段寄存器等4类. 1.通用寄存器有8个, 又可以分成2组,一组是数据寄存器(4个) ...

  3. 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 ...

  4. Http Url Get请求方式需要对中文参数进行编码

    public static void main(String[] args) { try { String mytext = java.net.URLEncoder.encode("上海南站 ...

  5. Sqli-labs less 26

    Less-26 TIPS:本关可能有的朋友在windows下无法使用一些特殊的字符代替空格,此处是因为apache的解析的问题,这里请更换到linux平台下. 本关结合25关,将空格,or,and,/ ...

  6. 斌哥的 Docker 进阶指南

    过去的一年中,关于 Docker 的话题从未断过,而如今,从尝试 Docker 到最终决定使用 Docker 的转化率依然在逐步升高,关于 Docker 的讨论更是有增无减.另一方面,大家的注意力也渐 ...

  7. 为什么主流网站无法捕获 XSS 漏洞?

    二十多年来,跨站脚本(简称 XSS)漏洞一直是主流网站的心头之痛.为什么过了这么久,这些网站还是对此类漏洞束手无策呢? 对于最近 eBay 网站曝出的跨站脚本漏洞,你有什么想法?为什么会出现这样的漏网 ...

  8. NDK 编译可执行程序

    以Hello Android工程为例. 建立好工程hello-a,在jni目录下创建文件hello-a.c,文件内容如下.(注意是jni目录,使用src目录编译会出错) #include <st ...

  9. 2013 ACM/ICPC Asia Regional Online —— Warmup

    1003 Rotation Lock Puzzle 找出每一圈中的最大值即可 代码如下: #include<iostream> #include<stdio.h> #inclu ...

  10. volatile 关键字的复习

    今天早上看何登成的微博(http://hedengcheng.com/?p=725) 对volatile 关键字语意进行了深入分析. 看完之后,用自己的话总结如下: 1.c/c++ volatile中 ...