很久没写题解了,去ec之前来填一填坑,希望能攒攒人品。。。

首先是去年上海F题。。uvalive7143

题意:

给n个人分 m间房子,每个房间的容量是已知的,其中有k对双胞胎,双胞胎可以看作相同的人,问总的方案数

其中n<=10W m=10 2k<=n

思路:

dp状态为, 前i个房子分完还剩多少对双胞胎(被拆散的不算)的方案数,转移结合组合数

代码:

#include <bits/stdc++.h>

using namespace std;
long long dp[][];
int a[];
int sum[];
long long f[];
long long inv[];
const long long mod=1e9+;
long long _pow(long long a,long long b)
{
long long res=;
while(b)
{
if(b&)
{
res=res*a%mod;
}
b>>=;
a=a*a%mod;
}
return res;
}
long long c(int n,int m)
{
if(n<m)
return ;
if(n<||m<)
{
return ;
}
return f[n]*inv[n-m]%mod*inv[m]%mod;
}
int main()
{
//freopen("in.txt","r",stdin);
int T,cas=;
scanf("%d",&T);
f[]=;
for(int i=;i<=;i++)
{
f[i]=f[i-]*i%mod;
}
for(int i=;i<=;i++)
{
inv[i]=_pow(f[i],mod-);
}
while(T--)
{
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
memset(dp,,sizeof(dp));
sum[]=;
for(int i=;i<=m;i++)
{
scanf("%d",a+i);
sum[i]=sum[i-]+a[i];
}
dp[][k]=;
for(int i=;i<=m;i++)
{
for(int j=;j<=k;j++)
{
int tot=sum[m]-sum[i-];
for(int t=;t<=j;t++)
{
long long d=dp[i-][j]*c(j,t)%mod*c(tot-(j-t)*-t,a[i]-t)%mod;
dp[i][j-t]=(dp[i][j-t]+d)%mod;
}
}
}
printf("Case #%d: %lld\n",cas++,dp[m][]);
}
return ;
}

然后是今年莫斯科赛区 H 。。cf gym 100972

题意:

有10W个数 每个数不超过255,要求一个子序列 a[] 使得子序列中 sum(i xor a[i]) 的值最大 其中 i 是选出的子序列中的下标

思路:

如果范围只有1000那就是傻逼题,现在有10W,需要考虑优化。

先考虑取子序列越长越好,发现有bug。然后想到由于每个值不大于255 显然如果选它,它对答案贡献只跟下标的后8位有关,少取256个和全取下标的后8位就循环了

因此最多少取255个

所以dp状态为 dp[i][j]表示前i个数有j个没取的最大值,转移的时候注意边界

代码:

#include <bits/stdc++.h>

using namespace std;
long long dp[][];
long long dp1[][];
int to[];
int a[];
int main()
{
for(int i=; i<; i++)
{
to[''+i]=i;
}
for(int i=; i<; i++)
{
to['A'+i]=+i;
}
int n;
scanf("%d",&n);
for(int i=; i<=n; i++)
{
char s[];
scanf("%s",s);
a[i]=;
for(int j=; j<; j++)
{
a[i]=*a[i]+to[s[j]];
}
}
long long ans=;
memset(dp,0xcf,sizeof(dp));
dp[][]=;
for(int i=; i<=n; i++)
{
for(int j=; j<min(i,); j++)
{
dp[i][j]=max(dp[i-][j]+(a[i]^(i--j)),dp[i-][j-]);
}
if(i<)
dp[i][i]=;
}
for(int i=; i<=; i++)
{
ans=max(ans,dp[n][i]);
}
printf("%I64d\n",ans);
return ;
}

最后是合肥d题。。hdu5555

题意:

有一个n*n的矩阵,对每个1<=x<=n ( x, 0)处都有一只frog,它们会向上跳,同时每个y ( 1 <= y <= n)有一个跳板,跳板可能是好的(长度为n),也可能是坏的 (长度小于n)。已知frog们最多会跳10个坏的跳板, 现在要在跳板上的某些位置放n个药丸(每个跳板一个),问所有的frog都恰好吃一个药丸 并且能跳出矩阵的方案数

思路:

先考虑坏的跳板,由于每个x坐标最多有十个坏的,可以状压它们,代表这10个有没有被前面的frog用过(即在前面frog的 x 坐标处放过了药丸),我的代码里为1代表没被用

注意在状态转移的过程中,某一个frog可能是在自己的坏跳板上吃了药丸,还可能在 好的跳板上吃了药丸,如果对每个frog 都向好的跳板转移,显然好的跳板是不够用的,那么怎么处理呢?

思考后容易发现其实不需要处理,因为有且只有n个 药丸,如果前面某个跳板 还没有被使用就已经不能用了 显然这是一个非法的状态,那么直接不进行转移就好了

最后的答案就是dp[n][0]* (好的跳板个数)! ,为什么要乘阶乘呢,因为显然好的跳板位置是不同的,如果由不同的frog使用了 那么方案也是不同的

感觉有点说不清楚了,具体见代码

代码:

#include <bits/stdc++.h>

using namespace std;

const long long mod=;
struct node
{
int l, r;
}; vector<node> v;
vector<int> g[];
long long dp[][<<];
int l[];
int r[];
int getnum(int x,int t)
{
int res=-;
for(int i=; i<(int)g[t].size(); i++)
{
if(g[t][i]==x)
res=i;
}
return res;
}
int bz(int st,int now)
{
return ((st>>(now+))<<(now+)) + (st&((<<now)-));
}
long long f[];
int main()
{
f[]=;
for(int i=; i<=; i++)
{
f[i]=f[i-]*i%mod;
}
freopen("in.txt","r",stdin);
int T,cas=;
scanf("%d",&T);
while(T--)
{
v.clear();
for(int i=; i<=; i++)
{
g[i].clear();
}
int nn=;
int n,x,y;
scanf("%d",&n);
for(int i=; i<n; i++)
{
scanf("%d",l+i);
}
for(int i=; i<n; i++)
{
scanf("%d",r+i);
}
for(int i=; i<n; i++)
{
x=l[i],y=r[i];
if(y-x+<n)
{
v.push_back(node{x,y});
}
else
{
nn++;
}
}
for(int i=; i<(int)v.size(); i++)
{
for(int j=v[i].l; j<=v[i].r; j++)
{
g[j].push_back(i);
}
}
int ok=;
for(int i=; i<=n; i++)
{
if((int)g[i].size()>)
{
ok=;
}
}
if(!ok)
{
printf("Case #%d: 0\n",cas++);
continue;
}
memset(dp,,sizeof(dp));
dp[][]=;
for(int i=; i<=n; i++)
{
for(int j=; j<(<<(int)g[i-].size()); j++)
{
int st=(<<(int)g[i].size())-;
if(dp[i-][j]==)
continue;
ok=;
for(int k=; k<(int)g[i-].size(); k++)
{
if(j&(<<k))
{
if(v[g[i-][k]].r<i)
{
ok=;
}
}
else
{
if(v[g[i-][k]].r>=i)
{
int now=getnum(g[i-][k],i);
st=bz(st,now);
}
}
}
if(ok)
{
for(int k=; k<(int)g[i].size(); k++)
{
if(st&(<<k))
{
dp[i][bz(st,k)]+=dp[i-][j];
dp[i][bz(st,k)]%=mod;
}
}
dp[i][st]+=dp[i-][j];
dp[i][st]%=mod;
}
}
}
printf("Case #%d: %I64d\n",cas++,f[nn]*dp[n][]%mod);
}
return ;
}

更新一波题解(最近做的三个dp题)的更多相关文章

  1. 斐波那契数列的三种C++实现及时间复杂度分析

    本文介绍了斐波那契数列的三种C++实现并详细地分析了时间复杂度. 斐波那契数列定义:F(1)=1, F(2)=1, F(n)=F(n-1) + F(n-2) (n>2) 如何计算斐波那契数 F( ...

  2. 某个应用的CPU使用率居然达到100%,我该怎么做?(三)

    某个应用的CPU使用率居然达到100%,我该怎么做?(三) 1. 引 你们好,可爱的小伙伴们^_^! 咱们最常用什么指标来描述系统的CPU性能呢?我想你的答案,可能不是平均负载,也不是CPU上下文切换 ...

  3. 古韵之乞巧 题解 dp题

    [noip模拟赛1]古韵之乞巧   描述 闺女求天女,更阑意未阑. 玉庭开粉席,罗袖捧金盘. 向月穿针易,临风整线难. 不知谁得巧,明旦试相看. ——祖咏<七夕> 女子乞巧,是七夕的重头戏 ...

  4. 洛谷P3502 [POI2010]CHO-Hamsters感想及题解(图论+字符串+矩阵加速$dp\&Floyd$)

    洛谷P3502 [POI2010]CHO-Hamsters感想及题解(图论+字符串+矩阵加速\(dp\&Floyd\)) 标签:题解 阅读体验:https://zybuluo.com/Junl ...

  5. 你只是看起来很努力(只是做了一遍真题,草草的对了一遍答案,然后冲出自习室继续她学生会的事情了,骗自己更容易)good——想起了自己在六大时候的无奈

    (转)你只是看起来很努力一次上课,一个女孩子垂头丧气的跟我说,老师,我考了四次四级,还没过,究竟是为什么. 我说,你真题做了吗?单词背了吗?她拿出已经翻破了的真题,跟我说,你讲的所有的题目我连答案都记 ...

  6. 20165237 2017-2018-2 《Java程序设计》第四周考试补做及2-3章编程题

    20165237 2017-2018-2 <Java程序设计>第四周考试补做及2-3章编程题 测试JDB: 用JDB调试上一个程序,输入1.2.3: 2-3章编程题代码托管 (程序的运行结 ...

  7. 斐波那契数列 矩阵乘法优化DP

    斐波那契数列 矩阵乘法优化DP 求\(f(n) \%1000000007​\),\(n\le 10^{18}​\) 矩阵乘法:\(i\times k\)的矩阵\(A\)乘\(k\times j\)的矩 ...

  8. 【题解】ARC101F Robots and Exits(DP转格路+树状数组优化DP)

    [题解]ARC101F Robots and Exits(DP转格路+树状数组优化DP) 先删去所有只能进入一个洞的机器人,这对答案没有贡献 考虑一个机器人只能进入两个洞,且真正的限制条件是操作的前缀 ...

  9. mysql技巧:如果记录存在则更新/如果不存在则插入的三种处理方法

    先建一个表,便于后面讨论: CREATE TABLE `t_emp` ( `f_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键id', `f_em ...

随机推荐

  1. 认识k_BackingField【转】

    事情从Json的序列化和反序列化说起. 在C#2.0的项目中,以前经常使用Json.Net实现序列化和反序列化.后来从c#3.0中开始使用新增的DataContractJsonSerializer进行 ...

  2. 在eclipse下面搭建Clojure开发运行环境

    打开eclipse,点击菜单栏“help->Install New Software...", 然后,点击”add“, 在Location处输入 http://ccw.cgrand.n ...

  3. Xcode添加静态库以及编译选项配置常见问题

    一,Xcode编译出现Link错误,出现"duplicate symbols for architecture i386 clang"提示.问题:链接时,项目有重名文件.解决:根据 ...

  4. 浅谈 trie树 及其实现

    定义:又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构, 如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树. 核心思想:是空间换时间.利用字符串的公共前缀来降低查询时间的开 ...

  5. Linux下安装SVN服务(CentOS7下)

    1. 安装 centos(我这里使用的是CentOS7)下yum命令即可方便的完成安装 测试安装是否成功: 2. 建立版本库 创建svn数据目录(subversion默认是把/var/svn作为数据根 ...

  6. HTML5拖放API

    拖放事件事件提供了拖放可以控制几乎所有方面的拖放操作.棘手的部分是确定每个事件触发:在拖项目火:别人火下降的目标.拖动项时,以下事件(按照这个顺序): 拖曳开始拖dragend此刻你把鼠标按钮和开始移 ...

  7. TC2.0中怎样调用汇编程序

    转载于: TC2.0中怎样调用汇编程序 一.概述 TC是美国BORLAND 公司在IBM PC机上开发的一个高效.优化的C编译程序,它自带高效的全屏幕编辑程序,在集成开发环境下可支持编辑.编译.连接调 ...

  8. CSS HACK的方法

    所有浏览器 通用 height: 100px; IE6 专用 _height: 100px; IE7 专用 *+height: 100px; IE6.IE7 共用 *height: 100px; IE ...

  9. linux中VI编辑器使用个人记录

    VI编辑器有三种编辑模式:命令模式.最后行模式.文本编辑模式 启动VI后进入的第一种模式是”命令模式“.从命令模式可进入最后行模式和编辑模式.而后两种模式之间不能直接切换.必须按ESC键退回到命令模式 ...

  10. BZOJ 3893 Cow Jog

    Description The cows are out exercising their hooves again! There are \(N\) cows jogging on an infin ...