hdu5396 Expression 区间dp +排列组合
#include<stdio.h>
#include<string>
#include<map>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
const int N=105;
const int MOD=1e9+7;
int n;
int a[N];
char ch[N];
void rd(int&x){
char ch;
for(ch=getchar();ch<'0' || ch>'9';ch=getchar());
x=0;
for(;ch>='0' && ch<='9';ch=getchar()) x=x*10+ch-'0';
}
long long res;
long long sum[N][N][N]; /*sum[i][j][k]表示区间i到j最后一个取第k个符号的答案和 ,sum[i][j][n+1]表示区间i到的答案总和*/
long long A[N];
long long calc(long long x,long long y,char c){
if(c=='+') return (x+y)%MOD;
else if(c=='-') return (x-y+MOD)%MOD;
else return (x*y)%MOD;
}
long long C[N][N];
void solve(){
memset(sol,0,sizeof sol);
memset(sum,0,sizeof sum);
for(int i=1;i<=n;i++){
sum[i][i][n+1]=a[i];
}
for(int i=1;i<n;i++){
sum[i][i+1][n+1]=sum[i][i+1][i]=calc(a[i],a[i+1],ch[i]);
}
for(int j=3;j<=n;j++)
for(int i=1;i+j-1<=n;i++){
int l=i,r=i+j-1;
for(int k=l;k<r;k++){
if(ch[k]=='+'){
/*
第k个符号左边 第l到k个数字。这个区间的方案个数 A[k-l] sum[l][k][n+1] l到k的和
第k个符号右边 第k+1到r个数字 这个区间的方案个数 A[r-k-1] sum[k+1][r][n+1] k+1到r的和
设左边 A[k-l]个值 a1,a2, ........ ai指的都是左边这个区间由某一顺序得到的一个值,能够将它和一个操作序列等同
设右边 A[r-k-1] 个值 b1,b2, ........
(a1+a2........) + (b1,b2.............) 对于每一个a,被加A[r-k-1]次 ,对于每一个b。被加A[k-l]次
减法同理
乘法特殊一点
(a1+a2........) * (b1,b2.............) 乘法分配率,直接将两部分的总和相乘就可以
*/
sum[l][r][k]=(sum[l][k][n+1]*A[r-k-1]+sum[k+1][r][n+1]*A[k-l])%MOD;
}else if(ch[k]=='-'){
sum[l][r][k]=(sum[l][k][n+1]*A[r-k-1]-sum[k+1][r][n+1]*A[k-l])%MOD;
sum[l][r][k]=(sum[l][r][k]+MOD)%MOD;
}else{
sum[l][r][k]=(sum[l][k][n+1]*sum[k+1][r][n+1])%MOD;
}
/*
之前算的是(左边的选择序列)+(右边的选择序列)。可是左右两边也有先后。再乘个组合数,比赛时这个想了好久才想到
对于上面的每一个ai和bj。他们在 遇到区间的最后一个操作符号后,须要再乘以一个组合数,由于之前的ai和bj是这种
ai:(操作1,操作2,操作3.。。。。操作n)+ bj:(操作n+1,操作n+2,操作n+3.。
。。
。)。可是不一定是ai的操作序列全在前面的。至于为什是组合不是排列
由于每一个ai和bj自己内部已经是有序了的。感觉这样讲的挺清楚了吧。自己比赛的时候这里卡了挺就久的。可是细致想一下。还是能够明确的
*/
sum[l][r][k]=(sum[l][r][k]*C[r-l-1][k-l])%MOD;
sum[l][r][n+1]=(sum[l][r][n+1]+sum[l][r][k])%MOD;
sum[l][r][n+1]=(sum[l][r][n+1]+MOD)%MOD;
}
}
printf("%I64d\n",sum[1][n][n+1]);
}
int main(){
#ifndef ONLINE_JUDGE
freopen("aaa","r",stdin);
#endif
int T;
int q;
A[0]=1;/*A是全排列 C是组合 ,预处理这两个*/
for(int i=1;i<N;i++) A[i]=(A[i-1]*i)%MOD;
for(int i=0;i<N;i++) C[i][0]=1;
for(int i=1;i<N;i++) for(int j=0;j<=i;j++) {
if(j==0 || j==i) C[i][j]=1;
else C[i][j]=(C[i-1][j-1]+C[i-1][j])%MOD;
}
while(~scanf("%d",&n)){
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
scanf("%s",ch+1);
solve();
}
return 0;
}
hdu5396 Expression 区间dp +排列组合的更多相关文章
- HDU 5151 Sit sit sit 区间DP + 排列组合
Sit sit sit 问题描述 在一个XX大学中有NN张椅子排成一排,椅子上都没有人,每张椅子都有颜色,分别为蓝色或者红色. 接下来依次来了NN个学生,标号依次为1,2,3,...,N. 对于每个学 ...
- [hdu5396 Expression]区间DP
题意:给一个表达式,求所有的计算顺序产生的结果总和 思路:比较明显的区间dp,令dp[l][r]为闭区间[l,r]的所有可能的结果和,考虑最后一个符号的位置k,k必须在l,r之间,则l≤k<r, ...
- 【BZOJ】2111: [ZJOI2010]Perm 排列计数 计数DP+排列组合+lucas
[题目]BZOJ 2111 [题意]求有多少1~n的排列,满足\(A_i>A_{\frac{i}{2}}\),输出对p取模的结果.\(n \leq 10^6,p \leq 10^9\),p是素数 ...
- 【BZOJ】4559: [JLoi2016]成绩比较 计数DP+排列组合+拉格朗日插值
[题意]n位同学(其中一位是B神),m门必修课,每门必修课的分数是[1,Ui].B神碾压了k位同学(所有课分数<=B神),且第x门课有rx-1位同学的分数高于B神,求满足条件的分数情况数.当有一 ...
- G.subsequence 1(dp + 排列组合)
subsequence 1 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524288K 64bit IO Format: %lld 题目描述 You are ...
- hdu 5396 Expression(区间dp)
Problem Description Teacher Mai has n numbers a1,a2,⋯,anand n−1 operators("+", "-&quo ...
- LightOJ1005 Rooks(DP/排列组合)
题目是在n*n的棋盘上放k个车使其不互相攻击的方案数. 首先可以明确的是n*n最多只能合法地放n个车,即每一行都指派一个列去放车. dp[i][j]表示棋盘前i行总共放了j个车的方案数 dp[0][0 ...
- HDU 5816 状压DP&排列组合
---恢复内容开始--- Hearthstone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java ...
- bzoj 3398 [Usaco2009 Feb]Bullcow 牡牛和牝牛——前缀和优化dp / 排列组合
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3398 好简单呀.而且是自己想出来的. dp[ i ]表示最后一个牡牛在 i 的方案数. 当前 ...
随机推荐
- IDEA 导入maven项目,显示:nothing to show
问题描述: IDEA 导入maven项目,import project,默认下一步,直到Select Maven projects to import界面无选项,提示:nothing to show ...
- 联想 S5【K520】免解锁BL 免rec 保留数据 Magisk Xposed 救砖 ROOT ZUI 3.7.490
>>>重点介绍<<< 第一:本刷机包可卡刷可线刷,刷机包比较大的原因是采用同时兼容卡刷和线刷的格式,所以比较大第二:[卡刷方法]卡刷不要解压刷机包,直接传入手机后用 ...
- HDU_1166_敌兵布阵
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- N18_二叉树的镜像
题目描述 操作给定的二叉树,将其变换为源二叉树的镜像. 输入描述: 二叉树的镜像定义:源二叉树 8 / \ 6 10 / \ / \ 5 7 9 11 镜像二叉树 8 / \ 10 6 / \ / \ ...
- 数据类型对应字节数(32位,64位 int 占字节数)
数据类型对应字节数(32位,64位 int 占字节数) 可用如sizeof(char),sizeof(char*)等得出 32位编译器: char :1个字节 char*(即指针变量): 4个字节(3 ...
- DBDA
<?php class DBDA{ public $host = "localhost"; //服务器地址 public $uid = "root"; / ...
- Go:条件语句、循环语句
一.条件语句 package main import ( "fmt" "io/ioutil" ) // if的条件不需要括号 func xx(i int) in ...
- 利用python去调用shell命令时候的踩到的坑
shell中 True的返回值是0 False的返回值是1 Python中 True的返回值是1 False的返回值是0
- 使用js将Unix时间戳转换为普通时间
var unixtime=1358932051;formatTime (time) { let unixtime = time let unixTimestamp = new Date(unixtim ...
- 洛谷 2777 [AHOI2016初中组]自行车比赛
[题解] 为了让某个选手能够获得总分第一,就让他最后一天的得分是n,并且让别的选手的得分的最大值尽量小.于是我们先把目前积分排序,并且让他们最后一天的排名刚好与积分排名相反.即某个积分排名为X的人最后 ...