【8.19校内测试】【背包】【卡特兰数】【数位dp】
早上随便搞搞t1t3就开始划水了,t2一看就是组合数学看着肚子疼...结果t1t3都a了??感天动地。
从小到大排序,从前到后枚举i,表示i是整个背包中不选的物品中代价最小的那个,即i不选,1到i-1全部都要选,i+1到n做背包(此时容量为m-pre),极限复杂度$O(n^3)$,可是我们在中间判断一下,当剩余容量比当前i代价小,break。可以减掉很大的复杂度!(cena评测最慢0.04s~
或者可以在枚举i时倒着枚举,每次背包就可以$O(n)$解决了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
#define RG register using namespace std; const int mod = ; int n, m, a[];
int f[]; int main ( ) {
freopen ( "gift.in", "r", stdin );
freopen ( "gift.out", "w", stdout );
scanf ( "%d%d", &n, &m );
for ( int i = ; i <= n; i ++ ) {
scanf ( "%d", &a[i] );
}
sort ( a + , a + + n );
ll ans = ; int sum = ;
for ( RG int i = ; i <= n; i ++ ) {
memset ( f, , sizeof ( f ) );
f[] = ;
for ( RG int k = i + ; k <= n; k ++ ) {
if ( m - sum < a[k] ) break;
for ( RG int j = m - sum; j >= a[k]; j -- ) {
f[j] = ( f[j] + f[j-a[k]] ) % mod;
}
}
for ( RG int j = max ( m - sum - a[i] + , ); j <= m - sum; j ++ )
ans = ( ans + f[j] ) % mod;
sum += a[i];
}
printf ( "%d", ans );
return ;
}
题意是要求该序列-1的累加和永远小于等于1的累加和的概率。经典的卡特兰数问题,在坐标系中,可以把-1看成向上走,把1看成向右走,最终目标是计算从原点走到$(n,m)$并且过程中不能超出到$y=x$这条直线的方案数。方案数为$C_{m+n}^m-C_{m+n}^{m-1}$,即$\frac{n-m+1}{n+1}$
#include<iostream>
#include<cstdio>
using namespace std; int main ( ) {
freopen ( "fseq.in", "r", stdin );
freopen ( "fseq.out", "w", stdout );
int T;
scanf ( "%d", &T );
while ( T -- ) {
int n, m;
scanf ( "%d%d", &n, &m );
if ( n < m ) printf ( "0.000000\n" );
else printf ( "%.6lf", ( double ) ( n - m + ) / ( double ) ( n + ) );
}
return ;
}
感觉我的方法是碰巧遇到可以过的类型了...如果题目不合法的对应关系改一下马上就会挂。
但是题目给的是对应不能相同嘛~我定义的$dp[dep][up][tot]$分别表示当前数的位置,是否顶上界,已经填了多少个数(抛开前导零,记忆化的时候会发现,除了顶上界的情况只会计算一次并且不会第二次返回,不顶上界的情况计算一次后每次都直接返回了,不管前面填的什么数和后面将填什么数...
可是对于这道题它恰好就是对的!在不顶上界的情况,所有数字都可以填,并且所有数字都有相同的不合法情况个数!所以直接记忆化就没有问题...
可是$yuli$dalao(%%%指出,只要把题稍微改一改,比如对应位置不能同时为质数之类的...每个数的方案数就不一样了!
所以正解是枚举数的长度,从前后同时填数即可。
#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std; ll dp[][][];
int num[], fi[]; ll dfs ( int dep, int up, int tot ) {
if ( dp[dep][up][tot] ) return dp[dep][up][tot];
if ( !dep && tot ) return ;
if ( !dep ) return ;
int MA = up ? num[dep] : ;
ll res = ;
for ( int i = ; i <= MA; i ++ ) {
if ( i == && !tot ) res += dfs ( dep - , up && i == MA,tot );
else if ( fi[tot + ] != i ) {
fi[dep] = i;
res += dfs ( dep - , up && i == MA, tot + );
fi[dep] = -;
}
}
dp[dep][up][tot] = res;
return res;
} ll work ( ll x ) {
int cnt = ;
memset ( fi, -, sizeof ( fi ) );
memset ( dp, , sizeof ( dp ) );
while ( x ) {
num[++cnt] = x % ;
x /= ;
}
return dfs ( cnt, , );
} int main ( ) {
freopen ( "lucky.in", "r", stdin );
freopen ( "lucky.out", "w", stdout );
ll x, y;
scanf ( "%I64d%I64d", &x, &y );
ll xx = work ( x - ), yy = work ( y );
printf ( "%I64d", yy - xx );
}
// wans
#include <bits/stdc++.h>
using namespace std; typedef long long ll;
ll l,r,dp[][][];
int tot,dig[];
bool vis[][][]; ll dfs(int dep,bool lf_up,bool rg_up) { if(vis[dep][lf_up][rg_up]) return dp[dep][lf_up][rg_up];
if(dep == tot - dep + ) {
if(lf_up && rg_up) return dig[dep];
else if(! lf_up) return ;
else if(lf_up) return dig[dep] + ;
}
if(dep > tot - dep + ) {
if(lf_up && rg_up) return ;
return ;
}
vis[dep][lf_up][rg_up] = true;
int up = lf_up ? dig[tot - dep + ] : ;
ll res = ;
for(int i = ;i <= up;i ++)
for(int j = ;j <= ;j ++) {
if(i == j) continue;
if(dep == && i == ) continue;
bool upup;
if(j > dig[dep]) upup = true;
else if(j < dig[dep]) upup = false;
else upup = rg_up;
res += dfs(dep + ,lf_up && (i == dig[tot - dep + ]),upup);
}
return dp[dep][lf_up][rg_up] = res;
} ll solve(ll s) { memset(vis,,sizeof(vis));
ll ss = s,ans = ;
tot = ;
while(s) {
dig[++ tot] = s % ;
s /= ;
}
ans += dfs(,,);
for(int i = ;i <= tot;i ++) dig[i] = ;
for(tot = tot - ;tot >= ;tot --) {
memset(vis,,sizeof(vis));
ans += dfs(,,);
}
return ans;
} int main( ) { freopen("lucky.in","r",stdin);
freopen("lucky.out","w",stdout);
scanf("%I64d%I64d",& l,& r);
ll ans1 = solve(l - );
ll ans2 = solve(r);
printf("%I64d",ans2 - ans1);
}
//yuli
【8.19校内测试】【背包】【卡特兰数】【数位dp】的更多相关文章
- 【10.17校内测试】【二进制数位DP】【博弈论/预处理】【玄学(?)DP】
Solution 几乎是秒想到的水题叻! 异或很容易想到每一位单独做贡献,所以我们需要统计的是区间内每一位上做的贡献,就是统计区间内每一位是1的数的数量. 所以就写数位dp辣!(昨天才做了数字统计不要 ...
- FZU 1064 教授的测试(卡特兰数,递归)
Problem 1064 教授的测试 Accept: 149 Submit: 364 Time Limit: 1000 mSec Memory Limit : 32768 KB Problem Des ...
- 2018.08.19 NOIP模拟 number(类数位dp)
Number 题目背景 SOURCE:NOIP2015-SHY-10 题目描述 如果一个数能够表示成两两不同的 3 的幂次的和,就说这个数是好的. 比如 13 是好的,因为 13 = 9 + 3 + ...
- 【BZOJ1662】[Usaco2006 Nov]Round Numbers 圆环数 数位DP
[BZOJ1662][Usaco2006 Nov]Round Numbers 圆环数 Description 正如你所知,奶牛们没有手指以至于不能玩"石头剪刀布"来任意地决定例如谁 ...
- 【BZOJ-1026】windy数 数位DP
1026: [SCOI2009]windy数 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 5230 Solved: 2353[Submit][Sta ...
- CCF 201312-4 有趣的数 (数位DP, 状压DP, 组合数学+暴力枚举, 推公式, 矩阵快速幂)
问题描述 我们把一个数称为有趣的,当且仅当: 1. 它的数字只包含0, 1, 2, 3,且这四个数字都出现过至少一次. 2. 所有的0都出现在所有的1之前,而所有的2都出现在所有的3之前. 3. 最高 ...
- bzoj 1026 [SCOI2009]windy数 数位dp
1026: [SCOI2009]windy数 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline ...
- luogu P2657 [SCOI2009]windy数 数位dp 记忆化搜索
题目链接 luogu P2657 [SCOI2009]windy数 题解 我有了一种所有数位dp都能用记忆话搜索水的错觉 代码 #include<cstdio> #include<a ...
- 【BZOJ 3326】[Scoi2013]数数 数位dp+矩阵乘法优化
挺好的数位dp……先说一下我个人的做法:经过观察,发现这题按照以往的思路从后往前递增,不怎么好推,然后我就大胆猜想,从前往后推,发现很好推啊,维护四个变量,从开始位置到现在有了i个数 f[i]:所有数 ...
随机推荐
- 初窥ThinkPHP
MVC全称(Model View Controller) Model:模型(可以理解位数据库操作模型) View:视图(视图显示) Controller:(控制器) 简单的说框架就是一个类的集合.集合 ...
- python第三方库之numpy基础
前言 numpy是python的科学计算模块,底层实现用c代码,运算效率很高.numpy的核心是矩阵narray运算. narray介绍 矩阵拥有的属性 ndim属性:维度个数 shape属性:维度大 ...
- python实战===python程序打包成exe
推荐PyInstaller项目www.pyinstaller.org 安装方法: 先跑pip install pywin32再跑pip install pyinstaller即可 可用一句命令打包 ...
- VI编辑,配置文件
1,VI编辑 vi 分为3种模式 1>一般模式: [Ctrl + f ] 下一页 [Ctrl + b ] 上一页 [n+ enter] 向下移动n行 eg:2 ...
- ACM——【百练习题备忘录】
1. 在做百练2807题:两倍时,错将判断语句写成 a/b ==2,正确写法是:a == b*2 因为C/C++int型做除法时自动舍入,如:5/2 == 2,但是 5 =/= 2*2. 2. 在做百 ...
- Nginx - 限制并发、限制访问速率、限制流量
1. 前言 本文针对 Nginx 的三个模块进行配置,并证实各自的功能特点: (1)limit_conn_zone 模块 - 限制同一 IP 地址并发连接数: (2)limit_request 模块 ...
- 微信小程序-textarea中的文本读取以及换行问题
今天客户那边要求textarea中输入的问题可以按回车键换行,而我使用的是bindinput获取值,但是呢bindinput 处理函数的返回值并不会反映到 textarea 上,按回车键导致点击换行符 ...
- SGU 205. Quantization Problem
205. Quantization Problem time limit per test: 0.25 sec. memory limit per test: 65536 KB input: stan ...
- java SE :文件基本处理 File、FileFilter、FileNameFilter
File 对目录及文件的创建.重命名.删除.文件列表.判断是否存在 构造函数 // 完整的目录或文件路径 public File(String pathname) //父级目录/文件路径+子级目 ...
- Sublime 编译运行JavaScript
Tools > Build System > New Build System... { "cmd": ["node", "$file&q ...