题目链接  飞扬的小鸟

考场的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优化)的更多相关文章

  1. NOIp 2014飞扬的小鸟【dp】By cellur925

    题目传送门 放在14年Day1T3的dp题目...应该比较看出来是dp算法吧,因为在本蒟蒻看来求最值的算法不清晰时就是dp了==. 状态还是比较好设计的,考虑到每个情况需要记录下的量:f[i][j]表 ...

  2. [NOIp 2014]飞扬的小鸟

    Description Flappy Bird 是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画面右方的管道缝隙.如果小鸟一不小心撞到了水管或者掉 ...

  3. 飞扬的小鸟 DP

    飞扬的小鸟 DP 细节有点恶心的DP,设\(f[i][j]\)表示横坐标为\(i\)(从\(0\)开始)高度为\(j\)时,屏幕点击的最小次数为\(f[i][j]\),转移便很好写了,这里要注意枚举当 ...

  4. [NOIP2014]飞扬的小鸟[DP]

    [NOIP2014]飞扬的小鸟 ——!x^n+y^n=z^n 题目描述: Flappy Bird 是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画 ...

  5. NOIP 提高组 2014 飞扬的小鸟(记录结果再利用的DP)

    传送门 https://www.cnblogs.com/violet-acmer/p/9937201.html 参考资料: [1]:https://www.luogu.org/blog/xxzh242 ...

  6. P1941 飞扬的小鸟[dp]

    题目描述 Flappy Bird是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画面右方的管道缝隙.如果小鸟一不小心撞到了水管或者掉在地上的话,便宣 ...

  7. NOIP2014飞扬的小鸟[DP][WRONG]

    坑人啊朴素的dp 75分 用了完全背包才是80分,结果普遍偏小 为什么啊啊啊啊啊 等以后再写一遍吧 #include<iostream> #include<cstdio> #i ...

  8. 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\}$ 然后考虑优化一下转移: 对于一系 ...

  9. NOIP 2014

    Prob.1 生活大爆炸版 石头剪刀布 模拟.代码: #include<cstdio> #include<cstring> #include<iostream> u ...

随机推荐

  1. jichu

    第 题 请编写函数 fun,其功能时:计算并输出当 x<0.97 时下列多项式的值,直到| sn-s(n-)|<0.000001 为止. Sn=+.5x+)/!x()+…+)()…..() ...

  2. Codeforces 664D Graph Coloring 二分图染色

    题意: 一个无向图的每条边为红色或蓝色,有这样一种操作:每次选一个点,使与其相邻的所有边的颜色翻转. 求解是否可以经过一系列操作使所有的边颜色相同,并输出最少操作次数和相应的点. 分析: 每个点要么选 ...

  3. Codeforces 35E Parade 扫描线

    题意: 给出\(n\)个底边在\(x\)轴上的矩形,求外面的轮廓线顶点. 分析: 将每个矩形拆成两个事件:\(\\\{ l, y, + \\\}\)和\(\\\{ r, y, - \\\}\)分别表示 ...

  4. mysql进阶三四五六

    排序查询 一.语法 select 查询表 from 表 where 筛选条件 order by 排序列表[asc / desc] 特点: 1.asc:升序 desc:降序 2.排序列表之中支持单字段, ...

  5. Sql获取数据表字段说明

    SELECT Sysobjects.name AS TABLE_NAME , syscolumns.Id , syscolumns.name AS COLUMN_NAME , systypes.nam ...

  6. Python+Selenium练习篇之11-浏览器上前进和后退操作

    本文来介绍上如何,利用webdriver中的方法来演示浏览器中地址栏旁边的前进和后退功能. 相关脚本代码如下: # coding=utf-8import timefrom selenium impor ...

  7. spaCy 并行分词

    spaCy 并行分词 在使用spacy的时候,感觉比nltk慢了许多,一直在寻找并行化的方案,好在找到了,下面给出spaCy并行化的分词方法使用示例: import spacy nlp = spacy ...

  8. unity c# 代码示例

    1. using UnityEngine; using System.Collections; public class AnimatorMove : MonoBehaviour { public f ...

  9. sql server 韩文查询匹配失败

    在SQL Server 中查询韩文信息时,没有匹配到对应的信息,检查程序后发现字段类型是nvarchar类型的没有问题, 打开存储过程后找到问题了:原来是拼接后的查询语句存储在一个varchar变量中 ...

  10. Mysql实战之索引

    author:JevonWei 版权声明:原创作品 索引基础: 索引:提取索引的创建在的表上字段中的数据,构建出一个独特的数据结构: 索引的作用:加速查询操作:副作用:降低写操作性能: 表中数据子集: ...