几道51nod上据说是提高组难度的dp题
听着懵逼做着傻逼。
每个格子只能经过一次,穿过上下界答案清0,不考虑穿的话就随便dp。如果要穿就是从尽可能上面的位置穿过上界,尽可能下面的位置穿过下界。
那么转移这一列之前找一下最上面最下面可以转移的位置。注意一下转移顺序什么的把细节写陈展就好了。
- //Achen
- #include<bits/stdc++.h>
- #define For(i,a,b) for(int i=(a);i<=(b);i++)
- #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
- #define Formylove return 0
- const int N=;
- typedef long long LL;
- typedef double db;
- using namespace std;
- int n,m,a[N][N];
- LL f[N][N][],ans;
- template<typename T> void read(T &x) {
- char ch=getchar(); x=; T f=;
- while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
- if(ch=='-') f=-,ch=getchar();
- for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
- }
- void GM(LL &x,LL y) { if(x<y) x=y; }
- //#define ANS
- int main() {
- #ifdef ANS
- freopen("1.in","r",stdin);
- //freopen("1.out","w",stdout);
- #endif
- read(n); read(m);
- For(i,,n) For(j,,m) read(a[i][j]);
- memset(f,,sizeof(f));
- LL inf=f[][][];
- For(i,,n) if(a[i][]!=-) {
- f[i][][]=f[i][][]=a[i][];
- }
- For(j,,m) {
- int pos1=,pos2=n+;
- For(i,,n) {
- if(a[i][j]==-) break;
- if(f[i][j][]!=inf) { pos1=i; break; }
- }
- Rep(i,n,) {
- if(a[i][j]==-) break;
- if(f[i][j][]!=inf) { pos2=i; break; }
- }
- For(i,,n) if(f[i][j][]!=inf&&i+<=n&&a[i+][j]!=-) GM(f[i+][j][],f[i][j][]+a[i+][j]);
- Rep(i,n,) if(f[i][j][]!=inf&&i->=&&a[i-][j]!=-) GM(f[i-][j][],f[i][j][]+a[i-][j]);
- if(pos1&&pos1!=n&&a[n][j]!=-) {
- int now=;
- GM(f[n][j][],a[n][j]);
- Rep(i,n-,pos1+) {
- if(a[i][j]!=-) { now+=a[i][j]; GM(f[i][j][],now); }
- else break;
- }
- }
- if(pos2!=n+&&pos2!=&&a[][j]!=-) {
- int now=;
- GM(f[][j][],a[][j]);
- For(i,,pos2-) {
- if(a[i][j]!=-) { now+=a[i][j]; GM(f[i][j][],now); }
- else break;
- }
- }
- For(i,,n) {
- if(f[i][j][]!=inf&&j+<=m&&a[i][j+]!=-) {
- GM(f[i][j+][],f[i][j][]+a[i][j+]);
- GM(f[i][j+][],f[i][j][]+a[i][j+]);
- }
- if(f[i][j][]!=inf&&j+<=m&&a[i][j+]!=-) {
- GM(f[i][j+][],f[i][j][]+a[i][j+]);
- GM(f[i][j+][],f[i][j][]+a[i][j+]);
- }
- }
- }
- /*For(i,1,n) {
- For(j,1,m) {
- LL a=f[i][j][0],b=f[i][j][1];
- if(a==inf) a=0; if(b==inf) b=0;
- printf("%lld(%lld) ",a,b);
- }
- puts("");
- }*/
- For(i,,n) For(j,,) GM(ans,f[i][m][j]);
- if(!ans) ans=-;
- printf("%lld\n",ans);
- Formylove;
- }
发现完美序列满足条件每次从当前完美序列去掉权值最大的数仍是完美序列。那么按权值从小到大往序列里放数,每次只能在两个比当前数小1的数之间或者序列前后放进一段当前数。
f[i][j][0/1/2]表示放到第i大的数,有j对连续的第i-1大数,序列前后有多少第i-1大数时的方案数。
转移用组合数转移,$\sum _i j=n$ 所以时间复杂度是n*100的
- //Achen
- #include<bits/stdc++.h>
- #define For(i,a,b) for(int i=(a);i<=(b);i++)
- #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
- #define Formylove return 0
- const int N=,p=;
- typedef long long LL;
- typedef double db;
- using namespace std;
- int n,a[N],cnt[N],mi,mx;
- LL C[][],f[N][][],ans;
- template<typename T> void read(T &x) {
- char ch=getchar(); x=; T f=;
- while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
- if(ch=='-') f=-,ch=getchar();
- for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
- }
- //#define ANS
- int main() {
- #ifdef ANS
- freopen("1.in","r",stdin);
- //freopen("1.out","w",stdout);
- #endif
- read(n);
- For(i,,) C[i][]=;
- For(i,,) For(j,,i) C[i][j]=(C[i-][j]+C[i-][j-])%p;
- For(i,,n) {
- read(a[i]);
- if(i==) mi=a[i],mx=a[i];
- else {
- mi=min(a[i],mi);
- mx=max(a[i],mx);
- }
- }
- For(i,,n) {
- a[i]=a[i]-mi+;
- if(a[i]<=n) cnt[a[i]]++;
- }
- n=mx-mi+;
- For(i,,n) if(!cnt[i]) {
- puts("");
- return ;
- }
- f[][cnt[]-][]=;
- For(i,,n) For(j,,cnt[i-]) For(k,,cnt[i]) {
- (f[i][cnt[i]-k][]+=(f[i-][j][]+f[i-][j][]+f[i-][j][])%p*C[j][k]%p*C[cnt[i]-][k-]%p)%=p;
- if(k>=&&j+>=k)
- (f[i][cnt[i]-k][]+=(f[i-][j][]+f[i-][j][]*)%p*C[j][k-]%p*C[cnt[i]-][k-]%p)%=p;
- if(k>=&&j+>=k)
- (f[i][cnt[i]-k][]+=f[i-][j][]*C[j][k-]%p*C[cnt[i]-][k-]%p)%=p;
- }
- For(i,,cnt[n]) ans=(ans+f[n][i][]+f[n][i][]+f[n][i][])%p;
- printf("%lld\n",ans);
- Formylove;
- }
按容积分为小于sqrt(n)的和大于sqrt(n)的两部分。小于根号的直接按余数分类单调队列优化多重背包地做。大于根号的因为选不到根号个,相当于没有数量限制的完全背包,用划分数的奥妙重重的方法优化。f[i][s]表示用i个数凑出s的方案数,
g[i][s]=g[i-1][s-(m+1)]+g[i-1][s-i];
也就是要么放进一个最小数,要么所有数+1。
因为发现把一种划分方法按数的大小排序,如
2 2 3 3 3 4 5 5 5 5 6 7 7 7
可以和上面两种操作的组合形成一一对应关系。
- //Achen
- #include<bits/stdc++.h>
- #define For(i,a,b) for(int i=(a);i<=(b);i++)
- #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
- #define Formylove return 0
- const int N=1e5+,p=;
- typedef long long LL;
- typedef double db;
- using namespace std;
- int n,m,of,og,f[][N],g[][N],ans;
- template<typename T> void read(T &x) {
- char ch=getchar(); x=; T f=;
- while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
- if(ch=='-') f=-,ch=getchar();
- for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
- }
- int mo(int x) { return x>=p?x-p:(x<?x+p:x); }
- //#define ANS
- int main() {
- #ifdef ANS
- freopen("1.in","r",stdin);
- //freopen("1.out","w",stdout);
- #endif
- read(n);
- m=sqrt(n);
- f[of][]=;
- For(i,,m) {
- of^=;
- For(w,,i-) {
- int pr=,sum=;
- for(int j=;(LL)j*i+w<=n;j++) {
- while(j-pr>i) {
- sum=mo(sum-f[of^][pr*i+w]); pr++;
- }
- f[of][j*i+w]=mo(f[of^][j*i+w]+sum);
- sum=mo(sum+f[of^][j*i+w]);
- }
- }
- }
- g[og][]=;
- ans=f[of][n];
- For(i,,m) {
- og^=; g[og][]=;
- For(s,,n)
- g[og][s]=mo((s-m->=?g[og^][s-(m+)]:)+(s-i>=?g[og][s-i]:));
- For(s,,n)
- ans=mo(ans+(LL)f[of][s]*g[og][n-s]%p);
- }
- printf("%d\n",ans);
- Formylove;
- }
答案就是每个物品有贡献的概率乘上价值,对每个物品单独考虑。f[i][j]表示其余的i个物品中选了j个比当前物品大的物品的概率,n^4dp即可。
- //Achen
- #include<bits/stdc++.h>
- #define For(i,a,b) for(int i=(a);i<=(b);i++)
- #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
- #define Formylove return 0
- const int N=;
- typedef long long LL;
- typedef double db;
- using namespace std;
- int n,m,k[N],c[N][N];
- db p[N][N],f[N][N],ans;
- template<typename T> void read(T &x) {
- char ch=getchar(); x=; T f=;
- while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
- if(ch=='-') f=-,ch=getchar();
- for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
- }
- //#define ANS
- int main() {
- #ifdef ANS
- freopen("1.in","r",stdin);
- //freopen("1.out","w",stdout);
- #endif
- read(n); read(m); m=min(n,m);
- For(i,,n) {
- read(k[i]);
- For(j,,k[i]) {
- read(c[i][j]);
- read(p[i][j]);
- p[i][j]/=10000.0;
- }
- }
- For(a,,n) For(b,,k[a]) {
- memset(f,,sizeof(f));
- f[][]=1.0; int o=;
- For(i,,n) if(i!=a) {
- o++;
- db p1=,p2=;
- For(j,,k[i]) {
- if(c[i][j]<c[a][b]||(c[i][j]==c[a][b]&&i<a)) p1+=p[i][j];
- else p2+=p[i][j];
- }
- For(j,,o) f[o][j]=f[o-][j]*p1+(j?f[o-][j-]*p2:);
- }
- db tp=;
- For(i,,m-) tp+=f[o][i];
- ans+=p[a][b]*tp*c[a][b];
- }
- printf("%lf\n",ans);
- Formylove;
- }
几道51nod上据说是提高组难度的dp题的更多相关文章
- newcoder NOIP提高组模拟赛C题——保护
我是发了疯才来写这道题的 我如果用写这道题的时间去写dp,我估计我能写上三四道 可怕的数据结构题 题目 这道题的鬼畜之处在于实在是不太好写 我们看到要求离树根尽量的近,所以我们很容易就能想到树上倍增, ...
- Vigenère 密码NOIP 2012 提高组 第一天 第一题
题目描述 16 世纪法国外交家 Blaise de Vigenère 设计了一种多表密码加密算法――Vigenère 密 码.Vigenère 密码的加密解密算法简单易用,且破译难度比较高,曾在美国南 ...
- luogu1003铺地毯[noip2011 提高组 Day1 T1]
题目描述 为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯.一共有 n 张地毯,编号从 1 到n .现在将这些地毯按照编号从小到大的顺序平行于 ...
- NOIP2014提高组 酱油记
NOIP考到哪里我就写到哪里好了. 2014/10/12 初赛 下午两点半开始考,我两点就到了.然后看到了QYL,NYZ,CZR等大神,先Orz了再说. 考试开始前,发现考场竟然没几个我认识的,不是按 ...
- [NOIP2012] 提高组 洛谷P1080 国王游戏
题目描述 恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右 手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这 n 位大臣排 成一排,国王站在队伍 ...
- [NOIP2011] 提高组 洛谷P1312 Mayan游戏
题目描述 Mayan puzzle是最近流行起来的一个游戏.游戏界面是一个 7 行5 列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上.游戏通关是指在规定 ...
- [NOIP2011] 提高组 洛谷P1003 铺地毯
题目描述 为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯.一共有 n 张地毯,编号从 1 到n .现在将这些地毯按照编号从小到大的顺序平行于 ...
- Codevs 3731 寻找道路 2014年 NOIP全国联赛提高组
3731 寻找道路 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 在有向图G中,每条边的长度均为1,现给定起点和终点,请你在图中找 ...
- NOIP2018提高组初赛知识点
(传说,在神秘的初赛中,选手们经常互相爆零以示友好……) 历年真题:ti.luogu.com.cn 以下标题中打*的是我认为的重点内容 一.关于计算机 (一)计算机组成 硬件组成: 1. 控制器(C ...
随机推荐
- kubeadm部署多master节点高可用k8s1.16.2
一.架构信息 系统版本:CentOS 7.6 内核:3.10.0‐1062.4.1.el7.x86_64 Kubernetes: v1.16.2 Dockerce: 19.03 推荐硬件配置:2核4 ...
- Android 为点击事件添加震动效果
Android 点击Button 实现震动效果 学习自:网络 Overview 在Android 的点击效果中,遇到震动效果的还是很多的. 接下来就让我们看一下如何实现震动效果. 所需要的权限 如果我 ...
- 【NOI2019模拟2019.6.29】字符串(SA|SAM+主席树)
Description: 1<=n<=5e4 题解: 考虑\(f\)这个东西应该是怎样算的? 不妨建出SA,然后按height从大到小启发式合并,显然只有相邻的才可能成为最优答案.这样的只 ...
- vue基础三
1.模板语法 在底层的实现上, Vue 将模板编译成虚拟 DOM 渲染函数.如果你熟悉虚拟 DOM 并且偏爱 JavaScript 的原始力量,你也可以不用模板,直接写渲染(render)函数,使用可 ...
- HZOI2019SF
Simulation Final 坑.下午我要爆零(RP++) upd: 哈哈哈哈哈哈哈哈哈哈我真的爆零了哈哈哈哈哈哈哈哈哈哈 关于细节, T1A了但是和T3交反了哈哈哈哈哈哈哈哈哈哈 我说我真的不是 ...
- [7.22NOIP模拟测试7]方程的解 题解(扩展欧几里得)
Orz 送分比较慷慨的一道题,疯狂特判能拿不少分. 对于$a>0,b>0$的情况: 用exgcd求出方程通解,然后通过操作得到最小正整数解和最大正整数解 他们以及他们之间的解满足等差数列性 ...
- Lilo的实现
书承上文:http://www.cnblogs.com/long123king/p/3549267.html 我们找一份Lilo的源码来看一下 http://freecode.com/projects ...
- 前端(十六)—— JavaScript盒子模型、JS动画、DOM、BOM
JS盒子模型.JS动画.DOM.BOM 一.JS盒模型 1.width | height parseInt(getComputedStyle(ele, null).getPropertyValue(' ...
- ActionContext 与 ServletActionContext获取Session的异同
1. ActionContext 在Struts2开发中,除了将请求参数自动设置到Action的字段中,我们往往也需要在Action里直接获取请求(Request)或会话(Session)的一些信息, ...
- 去除字符串中的HTML标签
背景:Kindeditor内容保存在数据库中的类型是text,包含文字和HTML标签. 需求:显示内容的前50个字(纯文字内容) 方法:将字段查出去除标签,截取前50 import java.util ...