太洗脑了;

  题目意思:初始队列是1,2, 3.......n ;在打乱这个队列切保证每个数字都不在原来的位置上的情况下给出一个具有+,- 的队列;

被打乱的队列 和 原来队列 对应位置的大小的关系是那个给定的 +,- 队列;

YY: 炸一看7S,n=20;状压DP 啊 开森的写完了,TTTTTTTT;这不是逗我玩呢么,他有1000组测试样例

还是DP !

  思路:

      每一位的数字有俩中分配方式 填补前面的+ 或者后面的-

      但是我们的DP 一般都是线性的不可能在枚举到一位的时候,左右的状态都被处理好

      所以我们选择一种处理方式

          1:从前往后处理,枚举到的数字往前面的+ 的位置放,或者记录下数字的个数等到枚举位置是- 时往里放

          2:从后往前 和一的刚好相反

      一般会选1 这样更舒服;

      对于要维护的值不难发现有 位置(pos),有多少个+号所在的位置没有确定数字(cnt[+]),剩余没有用到的数字;

对于选1 的要是枚举到的位数是   -   那么一定要找个数字把他填上   所以有下面的解法

  解法1:dp [i] [j] [k]  ::   枚举到位置I  时 ;

                 有J 个+号位置的数字好没有确定;

                      还有K个数字可用;

      所以很容易可以得到 当前位置是+ 的时候

          (1)选择把这个数字放到前面            

              dp[i][j][k]+= dp[i-1][j][k]*j;

          (2)选择吧这个数留下来为了填后面的减号

               dp[i][j][j]+= dp[i-1][j-1][k-1];

      当该位置是-    的时候

          (1)选择把这个数字放到前面,并找个前面剩下数字把这个位置填补

              dp[i][j][k]+= dp[i-1][j+1][k+1]*(j+1)*(k+1);

          (2)选择这个数字留下来,并找个前面的剩下数字把这个位置填补

                dp[i][j][k]+= dp[i-1][j][k]*j;

    至此dp[n-1][0][0]是答案;

代码1

#include <cstdio>
#include <string>
#include <algorithm>
#include <iostream>
#include <cstring>
using namespace std;
typedef long long LL;
char tmp[];
int n;
LL dp[][][];
int main()
{
while(~scanf("%s",tmp))
{
n=strlen(tmp);
if(tmp[]!='+' || tmp[n-]!='-')
{
puts("");
continue;
}
memset(dp,,sizeof dp);
dp[][][]=;
for(int i=;i<n;i++)
{
if(tmp[i]=='+')
{
for(int j=;j<=(i+);j++)
{
for(int k=;k<=(i+);k++)
{
if(i>=)
dp[i][j][k]+= dp[i-][j][k]*j;
if(i>=&&j>=&&k>=)
dp[i][j][j]+= dp[i-][j-][k-];
}
}
}
else
{
for(int j=;j<=(i+);j++)
{
for(int k=;k<=(i+);k++)
{
if(i>=)
dp[i][j][k]+= dp[i-][j+][k+]*(j+)*(k+);
if(j>=)
dp[i][j][k]+= dp[i-][j][k]*j;
}
}
}
}
cout<<dp[n-][][]<<endl;
}
return ;
}

优化:

  这个是不需要三个维度的  :

      试想当到达位置P 那么一共有P个数字被决定是

          放到+,-,还是留下了 ,

      对于留下的数字       和   剩下的    没有被分配数值的+号位置的数量

      有着相等的关系 理由如下

              (减号必须被分配)

          对于位置数 有加号和减号

             num[加号]+num[减号]    =   num[被分配的加号]+num[剩下的加号]+num[减号]=P;

          对于数字 有分配和未分配

             num[分配]+num[未分配]=      num[被分配到加号]+num[分配到减号]+num[未分配]=P;

          所以剩下的数字和未分配的加号是相等的

所以可以省一个维度

优化

#include <cstdio>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <cstring>
#include <cstdlib>
typedef long long LL;
using namespace std;
LL n;
LL dp[][];
char tmp[];
int main()
{
while(scanf("%s",tmp)!=EOF)
{
n=strlen(tmp);
if(tmp[]=='-'||tmp[n-]=='+')
{
puts("");
continue;
}
memset(dp,,sizeof(dp));
dp[][]=;
for(int i=; i<n; i++)
{
if(tmp[i]=='+')
for(int j=; j<=(i+); j++)
{
if(i>=&&j>=)
dp[i][j]+=dp[i-][j-];
if(i>=)
dp[i][j]+=dp[i-][j]*j;
}
else
for(int j=; j<=(i+); j++)
{
if(i>=)
dp[i][j]+=dp[i-][j+]*(j+)*(j+);
if(i>=)
dp[i][j] +=dp[i-][j]*j;
}
}
cout<<dp[n-][]<<endl;
}
return ;
}

HDU-4689 Derangement的更多相关文章

  1. HDOJ 4689 Derangement DP

    DP具体解释见: http://blog.csdn.net/liguan1/article/details/10468139 Derangement Time Limit: 7000/7000 MS ...

  2. HDU-4689 Derangement DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4689 题意:初始序列1,2...n,求所有满足与初始序列规定大小的错排数目.. 这道题目感觉很不错~ ...

  3. TOJ 4689: Sawtooth

    4689: Sawtooth Time Limit(Common/Java):1000MS/3000MS     Memory Limit:65536KByteTotal Submit: 26     ...

  4. HDOJ 2111. Saving HDU 贪心 结构体排序

    Saving HDU Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  5. 【HDU 3037】Saving Beans Lucas定理模板

    http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...

  6. hdu 4859 海岸线 Bestcoder Round 1

    http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...

  7. HDU 4569 Special equations(取模)

    Special equations Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u S ...

  8. HDU 4006The kth great number(K大数 +小顶堆)

    The kth great number Time Limit:1000MS     Memory Limit:65768KB     64bit IO Format:%I64d & %I64 ...

  9. HDU 1796How many integers can you find(容斥原理)

    How many integers can you find Time Limit:5000MS     Memory Limit:32768KB     64bit IO Format:%I64d ...

  10. hdu 4481 Time travel(高斯求期望)(转)

    (转)http://blog.csdn.net/u013081425/article/details/39240021 http://acm.hdu.edu.cn/showproblem.php?pi ...

随机推荐

  1. Enthought科学计算,数据分析

    Enthought Canopy: Easy Python Deployment Plus Integrated Analysis Environment for Scientific Computi ...

  2. 齐博软件(地方门户系统) 文件加密破解工具

    原文:齐博软件(地方门户系统) 文件加密破解工具 本程序为针对"齐博软件地方门户系统5.0官方原版"的破解工具,一个垃圾系统居然弄出这么恶心的加密方式,有个鸟用!以后见一个破一个! ...

  3. Cocos3d初探

    预计要相当长的一段时间内研究游戏引擎,在这里做一下过程中的备忘. 上一周项目须要,研究了一下cocos2d-x,本周接着来做cocos3d-x的代码研究 首先是搭建cocos3d-x的开发环境: 依据 ...

  4. 浅谈OCR之Onenote 2010

    原文:浅谈OCR之Onenote 2010 上一次我们讨论了Tesseract OCR引擎的用法,作为一款老牌的OCR引擎,目前已经开源,最新版本3.0中更是加入了中文OCR功能,再加上Google的 ...

  5. commons.net.telnet使用示例

    import org.apache.commons.net.telnet.TelnetClient; import java.io.IOException; public class TelnetDe ...

  6. poj3414(bfs)

    题目链接:http://poj.org/problem?id=3414 题意:给你两个容器 A  B 问是否能够经过有限的步骤倒水,得到容量为 C 的水,输出最小的步数,同时输出每一步的操作.如果不能 ...

  7. Django Form Media 阅读笔记

    ---恢复内容开始--- Form Media Rendering an attractive and easy-to-use Web form requires more than just HTM ...

  8. 关于Opencv2.4.x中stitcher类的简单应用

    1.opencv2.4以上版本有stitcher类,可以简单方便的实现图像的拼接,目前只是简单的测试一下stitcher类的拼接功能,也是纠结了好长时间,最终发现是要在链接库中加上opencv_sti ...

  9. FUDCon - FedoraProject

    FUDCon - FedoraProject FUDCon: Fedora Users and Developers Conference FUD: An acronym for Fear, Unce ...

  10. Android FragmentStatePageAdapter的使用Demo

    上一篇写过FragmentPagerAdapter,这篇来介绍FragmentStatePagerAdapter,那么两者之间有何差别呢: FragmentPagerAdapter很多其它的用于少量界 ...