太洗脑了;

  题目意思:初始队列是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. hdu 1007 最近点对问题(Splay解法)

    为什么要写这个题..经典啊,当然,别以为我用分治做的,不过主要思想还是那神奇的六个点共存(一个h*2h的矩形中最多能放下多少个点使得两两距离不超过h) 其实我是在这里看到的 http://commun ...

  2. map size mismatch; abort

    数据库启动时有莫名的提示map size mismatch; abort 原帖在这里:http://t.askmaclean.com/thread-1397-1-1.html 今天帮网友(centos ...

  3. JavaScript 中的事件类型1(读书笔记思维导图)

    Web 浏览器中可能发生的事件有很多类型.如前所述,不同的事件类型具有不同的信息,而“ DOM3级事件”规定了以下几类事件. UI(User Interface,用户界面)事件:当用户与页面上的元素交 ...

  4. RGB與CIELAB色彩空間轉換

    原地址:http://cg2010studio.wordpress.com/2012/10/02/rgb與cielab色彩空間轉換/ 之前有研究CIE L*a*b*色彩空間,現在想更進一步探討RGB色 ...

  5. centos 6.3 vnc连接—— catalog is not properly configured, attempting to determine an appropriate font p

    摘要:linux环境下,利用VNC连接远程桌面是经常用到的.这里,我们介绍centos上,利用VNC连接远程桌面的方法和常见的两个问题的解决方法1)由于字体问题,导致VNCserver无法启动 2)由 ...

  6. cocos2d-js-v3.0-rc0 下 pomelo-cocos2d-jsb native web 配置

    一.基本步骤 注意:pomelo-cocos2d-jsb 没实用 https://github.com/NetEase/pomelo-cocos2d-jsb,原因这个不是最新版,另外,componen ...

  7. HDOJ 4964 Emmet

    递归语法翻译... Emmet Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others ...

  8. JDBC/XML的一些基本使用

    原文:JDBC/XML的一些基本使用 一.知识点题目:JDBC核心API的使用 关键字:JDBC核心API 内容: 1)加载JDBC驱动: Oracle:Class.forName(“oracle.j ...

  9. AbstractQueuedSynchronizer的介绍和原理分析(转)

    简介 提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.该同步器(以下简称同步器)利用了一个int来表示状态,期望它能够成为实现大部分同步需求的基础.使用的方法是继承,子类通过 ...

  10. xcode project

    An Xcode project is a repository for all the files, resources, and information required to build one ...