【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]:所有数 ...
随机推荐
- [整理] magento搬家
将原来网站文件中的var文件中的cache和session文件删除,将media中的缓存文件删除.然后将所有文件制作成一个压缩包,以减少文件体积,方便转移. 将压缩包转移到新的服务器域名指向的文件夹, ...
- vue使用jsx/axios拦截器设置
最害怕的就是做过的事情,转几天又忘记了:写过的代码,也模模糊糊不知道哪里去了,所以告诉自己最好把每天遇到的问题记录下来,好,开始. 新公司要搭个vue后台框架,所以用了简简单单的 vue+iview+ ...
- 安装JDK环境变量的配置
设置环境变量 在java中需要设置三个环境变量(1.5之后不用再设置classpath了,但是个人强烈建议继续设置以保证向下兼容问题) JDK安装完成之后我们用来设置环境变量:右击”我的电脑“,选择” ...
- “您查看的网页正在试图关闭窗口。是否关闭此窗口”的屏蔽方法(JavaScript)
原文:http://www.cnblogs.com/tigerhuolh/archive/2011/04/14/2015634.html 用JS代码关闭窗口时会提示“您查看的网页正在试图关闭窗口.是否 ...
- 次短路经(dijsktra)
#include <cstdio>#include <cstring>#include <queue>#include <algorithm>#defi ...
- Gitlab部署及汉化操作
一.简介 GitLab是一个利用 Ruby on Rails 开发的开源应用程序,实现一个自托管的Git项目仓库,可通过Web界面进行访问公开的或者私人项目. GitLab拥有与Github类似的功能 ...
- C语言 五子棋2
#include<windows.h> #include<stdlib.h> #include<stdio.h> #include<conio.h> # ...
- csu 1598(KMP)
1598: 最长公共前缀 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 109 Solved: 92[Submit][Status][Web Boar ...
- 【Mac】Chrome中添加截图扩展插件FireShot方法
FireShot是一款可以使用谷歌浏览器快速捕捉当前网页中元素的chrome截图插件,在谷歌浏览器中安装FireShot插件以后可以对网页中整个屏幕或者是网页的部分视图进行截图操作,在截图之后用户还可 ...
- 常用 Java Profiling 工具的分析与比较
转自:http://www.ibm.com/developerworks/cn/java/j-lo-profiling/index.html 在 Java 程序的开发过程中,不可避免地会遇到内存使用. ...