NOIP 2014飞扬的小鸟(DP优化)
题目链接 飞扬的小鸟
考场的70分暴力(实际只有50分因为数组开小了……)
考场代码(数组大小已修改)
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i)
#define LL long long
#define fi first
#define se second const int INF = << ;
const int N = + ;
const int M = + ; int dp[M][N], x[N], y[N], u[N], d[N];
int n, m, q, ans, xn, ln, rn, _max, pos;
bool c[N]; int main(){ scanf("%d %d %d ", &n, &m, &q);
rep(i, , n - ) scanf("%d %d ", x + i, y + i);
rep(i, , n) u[i] = m, d[i] = ;
memset(c, false, sizeof c);
rep(i, , q){
scanf("%d %d %d ", &xn, &ln, &rn);
c[xn] = true;
u[xn] = rn - ;
d[xn] = ln + ;
}
//rep(i, 0, n) printf("%d %d\n", d[i], u[i]);
memset(dp, 0xff70, sizeof dp);_max = dp[][];
rep(i, , m) dp[][i] = ;
rep(i, , n - ){
rep(j, d[i], u[i]){
if (dp[i][j] >= _max) continue;
int k = j - y[i];
if (k >= && k <= m) dp[i + ][k] = min(dp[i + ][k], dp[i][j]);
k = j;int num = ;
while (true){
k += x[i]; ++num;
if (k > m) k = m;
if (k >= && k <= m) dp[i + ][k] = min(dp[i + ][k], dp[i][j] + num);
if (k == m) break;
}
}
} ans = _max;
rep(i, , m) ans = min(ans, dp[n][i]);
if (ans < _max){
printf("%d\n%d\n", , ans);return ;
} bool flag = false;
ans = ;
dec(i, n, ) {rep(j, , m) if (dp[i][j] < _max) { pos = i - ;flag = true; break;} if (flag) break;}
dec(i, pos, ) if (c[i]) ++ans;
printf("%d\n%d\n", , ans); return ;
}
然后回过来想正解。
其实我们把很多时间都浪费在这里了:
while (true){
k += x[i]; ++num;
if (k > m) k = m;
if (k >= && k <= m) dp[i + ][k] = min(dp[i + ][k], dp[i][j] + num);
if (k == m) break;
}
其实这一步可以转过来直接利用完全背包的性质优化一下。转移只要O(1)就可以了。
这道题细节还是很多的,比较容易写挂。
正解:
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i) const int INF = << ;
const int N = + ;
const int M = + ; int dp[N][M], x[N], y[N], u[N], d[N];
int n, m, q, ans, xn, ln, rn, _max, pos;
bool c[N]; int main(){ scanf("%d %d %d ", &n, &m, &q);
u[n] = m + ; d[n] = ;
rep(i, , n - ) scanf("%d %d ", x + i, y + i), u[i] = m + , d[i] = ; rep(i, , q){
scanf("%d %d %d ", &xn, &ln, &rn);
u[xn] = rn;
d[xn] = ln;
} rep(i, , n + ) rep(j, , m + ) dp[i][j] = INF; rep(i, , m) dp[][i] = ;
rep(i, , n){
rep(j, x[i - ], m){
dp[i][j] = min(dp[i][j], dp[i - ][j - x[i - ]] + );
dp[i][j] = min(dp[i][j], dp[i][j - x[i - ]] + );
} rep(j, m - x[i - ], m){
dp[i][m] = min(dp[i][m], dp[i - ][j] + );
dp[i][m] = min(dp[i][m], dp[i][j] + );
} rep(j, d[i] + , u[i] - ){
if (j + y[i - ] <= m) dp[i][j] = min(dp[i][j], dp[i - ][j + y[i - ]]);
} rep(j, , d[i]) dp[i][j] = INF;
rep(j, u[i], m) dp[i][j] = INF;
} ans = INF;
rep(i, , m) ans = min(ans, dp[n][i]);
if (ans != INF) return , printf("%d\n%d\n", , ans);
int t = q;
dec(i, n, ){
rep(j, , m) ans = min(ans, dp[i][j]);
if (ans != INF) break;
if (u[i] != m + ) --t;
} printf("%d\n%d\n", , t);
return ;
}
NOIP 2014飞扬的小鸟(DP优化)的更多相关文章
- NOIp 2014飞扬的小鸟【dp】By cellur925
题目传送门 放在14年Day1T3的dp题目...应该比较看出来是dp算法吧,因为在本蒟蒻看来求最值的算法不清晰时就是dp了==. 状态还是比较好设计的,考虑到每个情况需要记录下的量:f[i][j]表 ...
- [NOIp 2014]飞扬的小鸟
Description Flappy Bird 是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画面右方的管道缝隙.如果小鸟一不小心撞到了水管或者掉 ...
- 飞扬的小鸟 DP
飞扬的小鸟 DP 细节有点恶心的DP,设\(f[i][j]\)表示横坐标为\(i\)(从\(0\)开始)高度为\(j\)时,屏幕点击的最小次数为\(f[i][j]\),转移便很好写了,这里要注意枚举当 ...
- [NOIP2014]飞扬的小鸟[DP]
[NOIP2014]飞扬的小鸟 ——!x^n+y^n=z^n 题目描述: Flappy Bird 是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画 ...
- NOIP 提高组 2014 飞扬的小鸟(记录结果再利用的DP)
传送门 https://www.cnblogs.com/violet-acmer/p/9937201.html 参考资料: [1]:https://www.luogu.org/blog/xxzh242 ...
- P1941 飞扬的小鸟[dp]
题目描述 Flappy Bird是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画面右方的管道缝隙.如果小鸟一不小心撞到了水管或者掉在地上的话,便宣 ...
- NOIP2014飞扬的小鸟[DP][WRONG]
坑人啊朴素的dp 75分 用了完全背包才是80分,结果普遍偏小 为什么啊啊啊啊啊 等以后再写一遍吧 #include<iostream> #include<cstdio> #i ...
- luogu1941 [NOIp2014]飞扬的小鸟 (dp)
设f[i][j]为到达(i,j)这个位置的最小操作数 就有$f[i][j]=min\{f[i-1][j+Y[i-1]],f[i-1][j-X[i-1]*k]+k\}$ 然后考虑优化一下转移: 对于一系 ...
- NOIP 2014
Prob.1 生活大爆炸版 石头剪刀布 模拟.代码: #include<cstdio> #include<cstring> #include<iostream> u ...
随机推荐
- 动态规划:HDU1864-最大报销额(处理带小数的dp问题)
最大报销额 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Descriptio ...
- python实现分布式进程
今天用python实现分布式,基于python2.7,注意:在linux下执行测试通过,在windows测试失败.# -*- coding: utf-8 -*-__author__ = 'dell'i ...
- ObjectOutputStream和ObjectInputStream的简单使用
使用ObjectOutputStream往文本写内容时,首先在文本里面标记开始,然后是内容,最后加上结束标示.如果想再次往文本里面添加内容的话,就要加在开始标示之后和结束标示之前,不然会读取不到写入的 ...
- laravel5.2总结--本地化以及常量的使用
1.本地化 Laravel 的本地化功能提供方便的方法来获取多语言的字符串,让你的网站可以简单的支持多语言. 语言包存放在 resources/lang 文件夹的文件里.每一个子目录应该对应一种语言 ...
- leetcode 【 Search Insert Position 】python 实现
题目: Given a sorted array and a target value, return the index if the target is found. If not, return ...
- 使用jQuery ui创建模态表单
jQuery UI 是一个建立在 jQuery JavaScript 库上的小部件和交互库,可以使用它创建高度交互的 Web 应用程序. 在web页面的开发过程中,在添加元素的时候需要用到弹出窗口添加 ...
- Leetcode 655.输出二叉树
输出二叉树 在一个 m*n 的二维字符串数组中输出二叉树,并遵守以下规则: 行数 m 应当等于给定二叉树的高度. 列数 n 应当总是奇数. 根节点的值(以字符串格式给出)应当放在可放置的第一行正中间. ...
- Java学习6之泛型
1.泛型定义 1.泛型类: public class Generic <T>{ public void get(T t){ System.out.println(t); } } examp ...
- [oldboy-django][2深入django]学生管理(Form)-- 编辑(设置input标签属性,设置input标签默认显示值,设置input的类型)
1 django 后台实现设置input标签属性,设置input标签默认显示值,设置input输入框类型 # Form生成html标签 a. 通过Form生成Input输入框,Form标签,以及sub ...
- web访问流程
客户端发送请求—->httpd得到请求—->httpd解析请求的格式(html,css,jsp)—->请求相应的PHP解析—->PHP解析程序执行完毕—–>db(数据库) ...