《文章》陆游
文章本天成,妙手偶得之。
粹然无疵瑕,岂复须人为。
君看古彝器,巧拙两无施。
汉最近先秦,固已殊淳漓。
胡部何为者,豪竹杂哀丝。
后夔不复作,千载谁与期?

I. Space Station

大佬题解
上述题解写的非常棒!思路层层递进,而且马蜂好评

暴力:首先将原数组排序,然后dfs枚举选择顺序,如果当前和已经≥50\ge50≥50即可利用阶乘算出方案数,复杂度不可算

记忆化搜索:这里就牵扯到如何记忆化搜索?
正解非常巧妙,由于aia_iai​的范围很小,这里只记录每个值出现的次数,这个信息已经足够还原原数组的必要信息。

最巧妙的是hash记忆化,当所有数剩下的个数相同时,方案数相同。这里把记录次数的数组进行hash,那么就完成了记忆化!!!

如果想到上面这些,还不行仍然TLE 怎么卡都卡不过去Q-Q
注意到如果ai=0a_i=0ai​=0我们什么时候都可以选他,也就是它的选择不被约束,由此我们可以先将0剔除出来,最后直接算0对答案的贡献。
我们的选择是一个排序,只需要把这些0插到选择的过程中即可,最终答案需要乘以(cnt+1)×(cnt+2)×⋯×n(cnt+1)×(cnt+2)×\dots×n(cnt+1)×(cnt+2)×⋯×n
cnt是非零数的个数

#include<unordered_map>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=100010,mod=1e9+7;
const ull P=131;
int n;
int a[55];
ll fact[N];
unordered_map<ull,ll> dp;
void init()
{fact[0]=1;for(int i=1;i<=100000;i++) fact[i]=fact[i-1]*i%mod;
}
ll dfs(int u,int now)
{if(!u) return 1;if(now>=50) return fact[u];ull hash=0;for(int i=50;i;i--) hash=hash*P+a[i];if(dp[hash]) return dp[hash];ll res=0;for(int i=1;i<=now;i++){if(!a[i]) continue;a[i]--;res=(res+(a[i]+1)*dfs(u-1,now+i)%mod)%mod;a[i]++;}return dp[hash]=res;
}
int main()
{init();int now;cin>>n>>now;int cnt0=0,cnt1=0;for(int i=1;i<=n;i++){int x;cin>>x;if(!x) cnt0++;else a[x]++,cnt1++;}ll ans=dfs(cnt1,now);for(int i=n;i>=cnt1+1;i--)ans=(ans*i)%mod;cout<<ans<<'\n';return 0;
}

第一次见hash记忆化,非常巧妙!!!菜就多练, 要不然训练总挂机
要加油哦~

I. Space Station(hash记忆化+dp)相关推荐

  1. Codeforces Round #459 (Div. 2) C 思维,贪心 D 记忆化dp

    Codeforces Round #459 (Div. 2) C. The Monster 题意:定义正确的括号串,是能够全部匹配的左右括号串. 给出一个字符串,有 (.). ? 三种字符, ? 可以 ...

  2. 【线性 dp】A005_LC_不同的子序列(记忆化 / dp 分类讨论)

    一.Problem 给定一个字符串 S 和一个字符串 T,计算在 S 的子序列中 T 出现的个数. 题目数据保证答案符合 32 位带符号整数范围. 示例 1: 输入:S = "rabbbit ...

  3. 【01 dp】A005_LC_生成数组(暴搜 / 记忆化 / dp)

    一.Problem Given three integers n, m and k. Consider the following algorithm to find the maximum elem ...

  4. [区间记忆化dp入门][Bribe the Prisoners SPOJ - GCJ1C09C][Codeforces Round #505D (rated, Div. 1 + Div. 2, ba]

    Bribe the Prisoners SPOJ - GCJ1C09C 作为这类题代表,f[i][j]代表第i点到第j点单独处理的最值 这题关键:释放某个囚犯后,就把囚犯分成两段,两段互相独立 这类d ...

  5. 聪聪和可可(记忆化dp+数学期望)

    emmmm 输入格式 数据的第1行为两个整数N和E,以空格分隔,分别表示森林中的景点数和连接相邻景点的路的条数. 第2行包含两个整数C和M,以空格分隔,分别表示初始时聪聪和可可所在的景点的编号. 接下 ...

  6. 【网格 dp】A002_LC_摘樱桃 I~II 传纸条(基于对角线定理(记忆化 / dp))

    一.摘樱桃 I 一个N x N的网格(grid) 代表了一块樱桃地,每个格子由以下三种数字的一种来表示: 0 表示这个格子是空的,所以你可以穿过它. 1 表示这个格子里装着一个樱桃,你可以摘到樱桃然后 ...

  7. poj 1191 棋盘分割(记忆化dp+递归)

    根据这2个公式可以 得到 O^2 = sum(x1^2 + x2^2 + x3^2 +...xi^2)/n - 平均值^2 所以我们就是要使得总分的平方和尽量小-- 对于一次切割,可以横着切,可以竖着 ...

  8. BZOJ2719 - [Violet 4]银河之星 (记忆化搜索+hash)

    Description Input Output Solution 一看到这题的我是懵逼的,好像有好多状态,妈妈怎么办? 然而仔细读题目,转动我们的脑子可以发现,由于每个棋子可以向各个方向移3格,且只 ...

  9. Discovering Gold LightOJ - 1030[概率dp或者记忆化搜索]

    题目大意:有一个[1,n][1,n][1,n]的数轴,数轴上的每个对应位置上都有金矿,你初始位置是1,然后你每次都会投色子决定你下一步跳到哪里,如果你跳出了nnn,那么你就要重新投.问你跳到nnn的时 ...

最新文章

  1. cmake:在各级目录之间共享变量(cmake cache变量)
  2. 获取checkbox所选中的值
  3. Mycat和Mysql搭建高可用企业数据库集群
  4. 某度文库付费文档下载,实测可用~
  5. 光猫修改html灰色选项,电信光猫怎么设置(修改)wifi密码?
  6. centos6.2安装office及PDF阅读器
  7. Python 树状图怎么画
  8. 看看人家那系统设计做的,那叫一个优雅
  9. 个人网站引入B站视频播放,个人博客播放B站视频。【1080P】
  10. openssh-7.5p1升级
  11. 【SSLGZ 2812】2017年10月30日提高组T2 凤凰院真凶
  12. Flink 网络流控和反压剖析详解
  13. linux升级失败无法启动应用程序,Ubuntu升级后无法启动 kernel panic - not syncing
  14. 【DNS系列】什么是正向DNS和反向DNS
  15. 京东数据库泄露事件分析
  16. 分式化简结果要求_分式的化简(含答案)
  17. JSX 基本语法规则
  18. 【Python爬虫】 爬取京东商品图片并下载
  19. 大数据分析如何使用pandas进行时间序列分析
  20. win 和linux

热门文章

  1. c++经典编程题_全国青少年软件编程等级考试C语言经典程序题10道十
  2. 11尺寸长宽 iphone_新手必知LED显示屏尺寸规格及计算方法
  3. qt 调用qpainter_在Qt5.4中如何实现QOpenGLWidget和QPainter混合编程
  4. [mybatis]Getting Started
  5. [PAT乙级]1033 旧键盘打字(getline()读入)
  6. [C++11]使用using和typedef给模板定义别名
  7. [设计模式]代理模式
  8. [C++STL]C++ 实现map容器和set容器
  9. Chain of responsibility(职责链)--对象行为型模式
  10. catia如何整列加工_CATIA V5 R20加工模块的自动编程方法