BZOJ 4531: [Bjoi2014]路径
Description
一个无向图,每个节点有一个字符,问形成长度为k的的合法表达式的方案数.
Sol
DP.
\(f[i][o][p][0/1]\) 表示走 \(i\) 步,到 \(o\) ,有 \(p\) 个左括号没有匹配,是否有前导 \(0\) .
分类讨论+大力转移就可以了.
判断好多啊...写挂了好几次...原因就是 \(o\) 打成 \(i\) ...
几个判断我写出来吧...
'-' 前只能为 '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' '(' ')'
'+' '*' '/' 前只能为 '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' ')'
'(' 前只能为 '-' '+' '*' '/' '('
')' 前只能为 '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' ')'
'0' 前只能为 '1' '2' '3' '4' '5' '6' '7' '8' '9' '-' '+' '*' '/' '('
'1' '2' '3' '4' '5' '6' '7' '8' '9' 前只能为 '1' '2' '3' '4' '5' '6' '7' '8' '9' '-' '+' '*' '/' '('
Code
/**************************************************************
Problem: 4531
User: BeiYu
Language: C++
Result: Accepted
Time:32 ms
Memory:1716 kb
****************************************************************/ #include<cstdio>
#include<iostream>
using namespace std; #define debug(a) cout<<#a<<"="<<a<<" "
typedef long long LL;
const int N = 22;
const int K = 35;
const LL Mo = 1000000007; int n,m,k;LL ans;
char c[N];
int a[N],g[N][N];
LL f[K][N][K][2]; inline int in(int x=0,char ch=getchar()){ while(ch>'9'||ch<'0') ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x; } int main(){
// freopen("in.in","r",stdin);
// freopen("out.out","w",stdout); n=in(),m=in(),k=in();
scanf("%s",c+1);
for(int i=1;i<=n;i++){
if(c[i]=='-') a[i]=10;
else if((c[i]>'9'||c[i]<'0')&&c[i]!='('&&c[i]!=')') a[i]=11;
else if(c[i]=='(') a[i]=12;
else if(c[i]==')') a[i]=13;
else a[i]=c[i]-'0';
} for(int i=1,u,v;i<=m;i++) u=in(),v=in(),g[u][v]=g[v][u]=1; for(int i=1;i<=n;i++) f[1][i][(a[i]==12)][(a[i]==0)]=(a[i]!=11&&a[i]!=13)?1:0; // for(int i=1;i<=n;i++) cout<<a[i]<<" ";cout<<endl; // for(int i=1;i<=n;i++){
// debug(f[1][i][0][0]),debug(f[1][i][0][1]),debug(f[1][i][1][0]),debug(f[1][i][1][1])<<endl;
// } for(int i=2;i<=k;i++){
for(int o=1;o<=n;o++){
for(int j=1;j<=n;j++){
if(!g[o][j]||o==j) continue;
for(int p=0;p<=i;p++)
switch(a[o]){
case 10://'-'
if(a[j]!=11&&a[j]!=10) f[i][o][p][0]=((f[i][o][p][0]+f[i-1][j][p][0])%Mo+f[i-1][j][p][1])%Mo;
break;//0 1 ( )
case 11://'+''*''/'
if(a[j]<10||a[j]==13) f[i][o][p][0]=((f[i][o][p][0]+f[i-1][j][p][0])%Mo+f[i-1][j][p][1])%Mo;
break;//0 1 )
case 12://'('
if(a[j]>9&&a[j]!=13&&p>0) f[i][o][p][0]=(f[i][o][p][0]+f[i-1][j][p-1][0])%Mo;
break;//- + (
case 13://')'
if(a[j]<10||a[j]==13) f[i][o][p][0]=((f[i][o][p][0]+f[i-1][j][p+1][0])%Mo+f[i-1][j][p+1][1])%Mo;
break;//0 1 )
default://num
if(a[o]==0){//1 - + (
if(a[j]<10) f[i][o][p][0]=(f[i][o][p][0]+f[i-1][j][p][0])%Mo;
else if(a[j]!=13) f[i][o][p][1]=(f[i][o][p][1]+f[i-1][j][p][0])%Mo;
}else{//1 - + (
if(a[j]!=13) f[i][o][p][0]=(f[i][o][p][0]+f[i-1][j][p][0])%Mo;
}break;
}
}
}
}
for(int i=1;i<=n;i++) if(a[i]<10||a[i]==13) ans=(ans+f[k][i][0][0]+f[k][i][0][1])%Mo; // for(int i=1;i<=n;i++) debug(f[k].[i][0][0]),debug(f[k][i][0][1])<<endl; cout<<ans<<endl;
return 0;
}
BZOJ 4531: [Bjoi2014]路径的更多相关文章
- BZOJ.4530.[BJOI2014]大融合(LCT)
题目链接 BZOJ 洛谷 详见这 很明显题目是要求去掉一条边后两边子树sz[]的乘积. LCT维护的是链的信息,那么子树呢? 我们用s_i[x]来记录轻边连向x的子树的和(记作虚儿子),那么sum[x ...
- [bzoj 1471] 不相交路径 (容斥原理)
题目描述 给出一个N(n<=150)N(n<=150)N(n<=150)个结点的有向无环简单图.给出444个不同的点aaa,bbb,ccc,ddd,定义不相交路径为两条路径,两条路径 ...
- BZOJ4531: [Bjoi2014]路径
Description 在一个N个节点的无向图(没有自环.重边)上,每个点都有一个符号, 可能是数字,也可能是加号.减号.乘号.除号.小括号.你要在这个图上数 一数,有多少种走恰好K个节点的方法,使得 ...
- BZOJ:4530: [Bjoi2014]大融合
4530: [Bjoi2014]大融合 拿这题作为lct子树查询的练手.本来以为这会是一个大知识点,结果好像只是一个小技巧? 多维护一个虚边连接着的子树大小即可. #include<cstdio ...
- 【刷题】BZOJ 4530 [Bjoi2014]大融合
Description 小强要在N个孤立的星球上建立起一套通信系统.这套通信系统就是连接N个点的一个树. 这个树的边是一条一条添加上去的.在某个时刻,一条边的负载就是它所在的当前能够 联通的树上路过它 ...
- bzoj 2150 最小路径覆盖
最小路径覆盖问题是:给定一个DAG,该DAG的一个路径覆盖是一个路径的集合,使得每个点属于且仅属于其中一条路径,问题就是求一个大小最小的路径集合. 做法是将每个点A拆成两个点A1,A2,如果A-> ...
- bzoj 4530 [Bjoi2014]大融合——LCT维护子树信息
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4530 LCT维护子树 siz .设 sm[ ] 表示轻儿子的 siz 和+1(1是自己的si ...
- BZOJ 2306 幸福路径(DP)
题解来源:http://www.cnblogs.com/jianglangcaijin/p/3799494.html 最后必然是走了一条链,或者是一个环(一直绕),或者是一条链加一个环.设f[i][j ...
- bzoj 4530: [Bjoi2014]大融合【LCT】
新姿势,一般来讲LCT只能维护splay重边里的数据,而这里要求维护整颗子树的size 多维护一个sq表示当前点轻儿子的size和,si表示包括轻重边的整颗子树的大小 然后需要改sq的地方是link和 ...
随机推荐
- Nginx:Pitfalls and Common Mistakes
New and old users alike can run into a pitfall. Below we outline issues that we see frequently as we ...
- PHP ob系列函数详解
一. 相关函数简介: 1.Flush:刷新缓冲区的内容,输出. 函数格式:flush() 说明:这个函数经常使用,效率很高. 2.ob_start :打开输出缓冲区 函数 ...
- Reading With Purpose: A grand experiment
Reading With Purpose: A grand experiment This is the preface to a set of notes I'm writing for a sem ...
- C/C++宏中#与##的讲解
http://www.cnblogs.com/morewindows/archive/2011/08/18/2144112.html
- memcached命令行操作详解,命令选项的详细解释
连接到memcached命令行下: telnet 127.0.0.1 11211 1.set / add / replace : 格式:<command> <key> < ...
- Enabling and Mounting NFS on CoreOS
http://blog.scottlowe.org/2015/02/20/config-mount-nfs-coreos/ #cloud-config write-files: - path: /et ...
- [FMX] Android APP 启动黑屏优化补丁
使用说明 *************************************************** Android APP 启动黑屏优化补丁 作者: Swish, YangYxd 201 ...
- WEBSTORM 打开多个项目的方法
WebStorm默认情况下一次只能打开一个项目,这点很不爽,其实是可以设置的. 方法: File -> settings -> Directories -> Add Content ...
- Druid使用起步—在javaWeb项目中配置监控 连接池
当我们在javaWEB项目中使用到druid来作为我们的连接池的时候,一定不会忘了添加监控功能.下面我们就来看一下,在一个简单的web项目中(尚未使用任何框架)我们是如果来配置我们的web.xml来完 ...
- PHP访问MSSQL数据库(实例代码)
本例子只作为简单的引导,实现一个简单的查询: <!DOCTYPE HTML> <html lang="en-US"> <head> <t ...