HDU-4689 Derangement
太洗脑了;
题目意思:初始队列是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的更多相关文章
- HDOJ 4689 Derangement DP
DP具体解释见: http://blog.csdn.net/liguan1/article/details/10468139 Derangement Time Limit: 7000/7000 MS ...
- HDU-4689 Derangement DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4689 题意:初始序列1,2...n,求所有满足与初始序列规定大小的错排数目.. 这道题目感觉很不错~ ...
- TOJ 4689: Sawtooth
4689: Sawtooth Time Limit(Common/Java):1000MS/3000MS Memory Limit:65536KByteTotal Submit: 26 ...
- HDOJ 2111. Saving HDU 贪心 结构体排序
Saving HDU Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- 【HDU 3037】Saving Beans Lucas定理模板
http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...
- hdu 4859 海岸线 Bestcoder Round 1
http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...
- HDU 4569 Special equations(取模)
Special equations Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u S ...
- HDU 4006The kth great number(K大数 +小顶堆)
The kth great number Time Limit:1000MS Memory Limit:65768KB 64bit IO Format:%I64d & %I64 ...
- HDU 1796How many integers can you find(容斥原理)
How many integers can you find Time Limit:5000MS Memory Limit:32768KB 64bit IO Format:%I64d ...
- hdu 4481 Time travel(高斯求期望)(转)
(转)http://blog.csdn.net/u013081425/article/details/39240021 http://acm.hdu.edu.cn/showproblem.php?pi ...
随机推荐
- Java学习笔记——File类之文件管理和读写操作、下载图片
Java学习笔记——File类之文件管理和读写操作.下载图片 File类的总结: 1.文件和文件夹的创建 2.文件的读取 3.文件的写入 4.文件的复制(字符流.字节流.处理流) 5.以图片地址下载图 ...
- BT5 firefox Flash插件问题
今天在BT下安装了Nessus,好不容易安装好了,注册成功,本以为大功告成,但是在最后关头,却出现一个“未安装flash插件”错误,在bT下尝试着安装flahs插件,蛋碎一地,,,没能解决. 我的BT ...
- 彻底删除"提示删除文件和目录"时出错的文件或目录
当删除文件是出现上图时 能够用以下的方法删除文件 策略一:系统大法 第一招 进程帮你搞定 很多时候乱码文件名称里的文件是explorer.exe进程联系在一起的. 假设要删除的话能够这样:首先命令 ...
- 设计模式之——Factory(工厂模式)
工厂模式用于,通过统一的创建对象接口来创建对象,而子类可以决定对象的创建方式. class CObject { }; class CCar : public CObject { }; class CF ...
- Python编程中常用的12种基础知识总结
原地址:http://blog.jobbole.com/48541/ Python编程中常用的12种基础知识总结:正则表达式替换,遍历目录方法,列表按列排序.去重,字典排序,字典.列表.字符串互转,时 ...
- 2013 吉林通化邀请赛 D-City 离线型的并查集
题意:给定n个点和m条边,问你拆掉前i条边后,整个图的连同城市的数量. i从1到m. 思路:计算连通的城市,很容易想到并查集,但是题目里是拆边,所以我们可以反向去做. 存下拆边的信息,从后往前建边. ...
- File already exists: filesystem '/path/file', transaction svn常见错误解决方法
前言 多人任务基本都会用到SVN,于是提交的时候如果不先更新在提交或者操作顺序不对,会经常出现错误,其中File already exists: filesystem这个就是个常见问题,上网找了半天没 ...
- .net设计模式 - 单例模式
DoNet设计模式实例之单例模式( Singleton Pattern) 一 : 单例模式的简介:(Brief Introduction) 单例模式(Singleton Pattern),保证一个类只 ...
- centos安装Chromium
1. Change root user Shell su - ## OR ## sudo -i 0 1 2 3 4 su - ## OR ## sudo -i 2a. Install NCSU ...
- 使用SSIS对Dynamics CRM 系统进行数据迁移
嗨,各位.近期项目一直都非常忙,而且自己也一直在思考职业发展的问题,所以有非常长一段时间没静下心写几篇Blog了.近期我參与的项目是Dynamics CRM 2011 到 Dynamics CRM 2 ...