太洗脑了;

  题目意思:初始队列是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. Apache Commons IO入门教程(转)

    Apache Commons IO是Apache基金会创建并维护的Java函数库.它提供了许多类使得开发者的常见任务变得简单,同时减少重复(boiler-plate)代码,这些代码可能遍布于每个独立的 ...

  2. Direct UI

    在界面开发中,眼下DirectUI是个热门的技术名称,由于众多的知名公司都是用DirectUI方式作出了非常炫丽的界面.而对于大多数熟悉Win32控件,熟悉MFC开发的开发者来说,我们应该做何选择? ...

  3. XML语法规范

    1: 怎样声明一个xml文件 答:由2部分组成 声明部分,声明xml的版本号与编码(版本号仅仅有1.0) <? xml version="1.0" encoding=&quo ...

  4. Twenty Newsgroups Classification任务之二seq2sparse(5)

    接上篇blog,继续分析.接下来要调用代码如下: // Should document frequency features be processed if (shouldPrune || proce ...

  5. Java面向对象基础二

    1.对象的用法 2.多对象的创建方法 3.匿名对象的创建和用法

  6. 为什么国外程序员爱用苹果Mac电脑?(转)

    Mac 在国外很受欢迎,尤其是在 设计/web开发/IT 人员圈子里.普通用户喜欢 Mac 可以理解,毕竟 Mac 设计美观,简单好用,没有病毒.那么为什么专业人士也对 Mac 情有独钟呢?从个人使用 ...

  7. Codeforces Round #246 (Div. 2) D. Prefixes and Suffixes(后缀数组orKMP)

    D. Prefixes and Suffixes time limit per test 1 second memory limit per test 256 megabytes input stan ...

  8. OpenLayers学习笔记4——使用jQuery UI实现測量对话框

    OpenLayers学习最好的方式就是跟着其自带的演示样例进行学习,另外对web前端的开发设计要了解,慢慢积累,这样在一般的小项目中应该是足够用了. 本篇參照量測demo实现对话框形式的量測,抛砖引玉 ...

  9. Entity Framework6使用SQL Server Compact免安装部署

    原文:Entity Framework6使用SQL Server Compact免安装部署 使用Nuget安装以下包: EntityFramework.6.0.2 EntityFramework.Sq ...

  10. JAVA取整以及四舍五入

    JAVA取整以及四舍五入 import java.math.BigDecimal; //引入这个包 public class Test { public static void main(String ...