前言

今天做的是是2010年提高组和NOI的题目,做过几道原题,但是还是爆炸了,我真的太弱了。

t1-乌龟棋

https://www.luogu.org/problemnew/show/P1541
这道题目还是比较简单的,差不多是三年做过的题目。
简单的DP,定义状态是\(f[i][j][k][l]\)表示i个1的卡牌,j个2的卡牌,k个3的卡牌,l个4的卡牌时的最大分数。
O(n^4)的暴力转移
\[f[i][j][k][l]=max(f[i-1][j][k][l]+a[tmp])\]
\[f[i][j][k][l]=max(f[i][j-1][k][l]+a[tmp])\]
\[f[i][j][k][l]=max(f[i][j][k-1][l]+a[tmp])\]
\[f[i][j][k][l]=max(f[i][j][k][l-1]+a[tmp])\]
其中tmp表示的是当前的位置,因为我们已知用了各个卡牌有多少张,那么就可以直接推出当前的位置。

#include <bits/stdc++.h>
#define ll long long
#define ms(a, b) memset(a, b, sizeof(a))
#define inf 0x3f3f3f3f
#define N
using namespace std;
template <typename T>
inline void read(T &x) {
    x = 0; T fl = 1;
    char ch = 0;
    while (ch < '0' || ch > '9') {
        if (ch == '-') fl = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = (x << 1) + (x << 3) + (ch ^ 48);
        ch = getchar();
    }
    x *= fl;
}
int f[45][45][45][45];
int n, m;
int a[355], b[10];
int main() {
    read(n); read(m);
    memset(f, 0, sizeof(f));
    memset(b, 0, sizeof(b));
    for (int i = 1; i <= n; i ++) read(a[i]);
    for (int i = 1; i <= m; i ++) {
        int x; read(x);
        b[x] ++;
    }
    f[0][0][0][0] = a[1];
    for (int i = 0; i <= b[1]; i ++) {
        for (int j = 0; j <= b[2]; j ++) {
            for (int k = 0; k <= b[3]; k ++) {
                for (int l = 0; l <= b[4]; l ++) {
                    int tmp = i + j * 2 + k * 3 + l * 4 + 1;
                    if (i) f[i][j][k][l] = max(f[i][j][k][l], f[i - 1][j][k][l] + a[tmp]);
                    if (j) f[i][j][k][l] = max(f[i][j][k][l], f[i][j - 1][k][l] + a[tmp]);
                    if (k) f[i][j][k][l] = max(f[i][j][k][l], f[i][j][k - 1][l] + a[tmp]);
                    if (l) f[i][j][k][l] = max(f[i][j][k][l], f[i][j][k][l - 1] + a[tmp]);
                }
            }
        }
    }
    printf("%d\n", f[b[1]][b[2]][b[3]][b[4]]);
    return 0;
}

t2-关押罪犯

https://www.luogu.org/problemnew/show/P1525
并查集裸题,我们设立两个集合分别表示当前的罪犯和及其补集,也就是判断他们能不能在一起。
考试的时候差一点就写炸了,因为在结构体里面重定义运算符好像会炸,应该是我太弱了,所以就打了一个不怎么美观的cmp。 ̄□ ̄||。但是还是只有90分,因为我电脑死机,重启之后重构代码,结尾忘掉输出0了。

#include <bits/stdc++.h>
#define ll long long
#define ms(a, b) memset(a, b, sizeof(a))
#define inf 0x3f3f3f3f
#define N 100005
using namespace std;
template <typename T>
inline void read(T &x) {
    x = 0; T fl = 1;
    char ch = 0;
    while (ch < '0' || ch > '9') {
        if (ch == '-') fl = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = (x << 1) + (x << 3) + (ch ^ 48);
        ch = getchar();
    }
    x *= fl;
}
struct edge {
    int u, v, dis;
}a[N];
int fa[N];
int n, m;
bool cmp(edge a, edge b) {
    return a.dis > b.dis;
}
int gf(int x) {
    return fa[x] == x ? fa[x] : fa[x] = gf(fa[x]);
}
int main() {
    freopen("prison.in","r",stdin);
    freopen("prison.out","w",stdout);
    read(n); read(m);
    for (int i = 1; i <= m; i ++) read(a[i].u), read(a[i].v), read(a[i].dis);
    for (int i = 1; i <= 2 * n; i ++) fa[i] = i;
    sort(a + 1, a + 1 + m, cmp);
    for (int i = 1; i <= m; i ++) {
        int p1 = gf(a[i].u), p2 = gf(a[i].v);
        if (p1 == p2) {
            printf("%d\n", a[i].dis);
            return 0;
        }
        fa[p1] = gf(a[i].v + n);
        fa[p2] = gf(a[i].u + n);
    }
    return 0;
}

t4-引水入城

https://www.luogu.org/problemnew/show/P1514
一道简单的搜索题+DP,但是我忘记输出了不能有的城市的个数,直接爆炸成70分。
我们在搜索的时候,记录最后一行线段的端点,然后就做一些线段覆盖的DP就好了。

#include <bits/stdc++.h>
#define ll long long
#define ms(a, b) memset(a, b, sizeof(a))
#define inf 0x3f3f3f3f
using namespace std;
template <typename T>
inline void read(T &x) {
    x = 0; T fl = 1;
    char ch = 0;
    while (ch < '0' || ch > '9') {
        if (ch == '-') fl = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = (x << 1) + (x << 3) + (ch ^ 48);
        ch = getchar();
    }
    x *= fl;
}
struct data {
    int l, r;
    bool operator <(const data &rhs) const {
        return l < rhs.l;
    }
}a[505];
int n, m, mp[505][505], f[505], cnt = 0;
bool vis[505][505] = {0}, ans[505] = {0};
void dfs(int x, int y, ll kkk) {
    vis[x][y] = 1;
    if (x == m) {
        ans[y] = 1;
        a[kkk].l = min(a[kkk].l, y);
        a[kkk].r = max(a[kkk].r, y);
    }
    if (mp[x + 1][y] < mp[x][y] && x != m && !vis[x + 1][y]) dfs(x + 1, y, kkk);
    if (mp[x - 1][y] < mp[x][y] && x != 1 && !vis[x - 1][y]) dfs(x - 1, y, kkk);
    if (mp[x][y + 1] < mp[x][y] && y != n && !vis[x][y + 1]) dfs(x, y + 1, kkk);
    if (mp[x][y - 1] < mp[x][y] && y != 1 && !vis[x][y - 1]) dfs(x, y - 1, kkk);
}
int main() {
    read(m); read(n);
    for (int i = 1; i <= n; i ++) a[i].l = f[i] = inf;
    f[0] = 0;
    for (int i = 1; i <= m; i ++) {
        for (int j = 1; j <= n; j ++)
            read(mp[i][j]);
    }
    for (int i = 1; i <= n; i ++) {
        dfs(1, i, i);
        memset(vis, 0, sizeof(vis));
    }
    for (int i = 1; i <= n; i ++) {
        if (!ans[i]) cnt ++;
    }
    if (cnt) {
        printf("0\n%d\n", cnt);
        return 0;
    }
    else {
        printf("1\n");
        for (int i = 1; i <= n; i ++) {
            for (int j = 1; j <= n; j ++) {
                if (i >= a[j].l && i <= a[j].r) f[i] = min(f[i], f[a[j].l - 1] + 1);
            }
        }
        printf("%d\n", f[n]);
    }
    return 0;
}

t4-超级钢琴

这道题目之前做过但是没有A掉,考场上面自己YY乱搞记得正解怎么搞,也不知道怎么回事就做出来了???
简要讲一下
先用前缀和处理数据,用st表预处理区间最小值,然后构建一个大根堆,队里存储左边界的范围(-1),右边界,以此为右边界的最大答案,最大答案时的左边界(-1),每次取出都把左边界的范围拆分成2份,维护一下就好了。

#include <bits/stdc++.h>
#define ll long long
#define ms(a, b) memset(a, b, sizeof(a))
#define inf 0x3f3f3f3f
#define pii pair<int, int>
#define Mp(a,b,c,d) make_pair(make_pair(a,b),make_pair(c,d))
#define N 500005
using namespace std;
template <typename T>
inline void read(T &x) {
    x = 0; T fl = 1;
    char ch = 0;
    while (ch < '0' || ch > '9') {
        if (ch == '-') fl = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = (x << 1) + (x << 3) + (ch ^ 48);
        ch = getchar();
    }
    x *= fl;
}
struct ST {
    int n;
    int f[N][24], Log[N], a[N];
    ST() {
        memset(f, 0, sizeof(f));
    }
    void init(int M, int *A) {
        n = M;
        for (int i = 1; i <= n; i ++) a[i] = A[i];
    }
    int mn(int l, int r) {
        return a[l] < a[r] ? l : r;
    }
    void make_ST() {
        for (int i = 2; i <= n; i ++) Log[i] = Log[i >> 1] + 1;
        for (int i = 1; i <= n; i ++) f[i][0] = i;
        for (int j = 1; (1 << j) <= n; j ++) {
            for (int i = 0; i + (1 << j) - 1 <= n; i ++) {
                f[i][j] = mn(f[i][j - 1], f[i + (1 << j - 1)][j - 1]);
            }
        }
    }
    int query(int l, int r) {
        if (l > r) return -1;
        int k = Log[r - l + 1];
        return mn(f[l][k], f[r - (1 << k) +1][k]);
    }
}ST;
priority_queue<pair<pii,pii> >q;
int n, m, L, R;
ll ans = 0;
int x, y, a, b, c, d;
int v[N], sum[N];
int main() {
    freopen("piano.in","r",stdin);
    freopen("piano.out","w",stdout);
    read(n); read(m); read(L); read(R);
    for (int i = 1; i <= n; i ++) {
        read(v[i]);
        sum[i] = sum[i - 1] + v[i];
    }
    ST.init(n, sum);
    ST.make_ST();
    for (int i = L; i <= n; i ++) {
        q.push(Mp(sum[i] - sum[ST.query(max(i - R, 0), i - L)], i, max(i - R, 0), i - L));
    }
    for (int i = 1; i <= m; i ++) {
        pii t1 = q.top().first, t2 = q.top().second;
        ans += t1.first, x = t1.second, a = t2.first, b = t2.second, y = ST.query(a, b);
        q.pop();
        c = ST.query(a, y - 1); d = ST.query(y + 1, b);
        if (c != -1) q.push(Mp(sum[x] - sum[c], x, a, y - 1));
        if (d != -1) q.push(Mp(sum[x] - sum[d], x, y + 1, b));
    }
    printf("%lld\n", ans);
    return 0;
}

[hgoi#2019/3/21]NOIP&NOI赛后总结的更多相关文章

  1. 2019.01.21 NOIP训练 可持久化序列【模板】(可持久化treap)

    传送门 题意简述:支持在把某个数插入到某版本的第k个位置,删除某版本第k个数,询问第k个数. 思路:用可持久化treaptreaptreap维护区间第kkk个位置的数是啥就可以了. 代码

  2. 2019.01.21 NOIP训练 ak树(点分治)

    传送门 题意简述:给一棵带权树,问在上面随机选两个点距离是4的倍数的概率. 思路: 由于总方案数为定值n2n^2n2,所以只用求总方案数. 这个跟聪聪可可差不多,可以用类似树形dpdpdp的方法边点分 ...

  3. 2019.3.18考试&2019.3.19考试&2019.3.21考试

    2019.3.18 C O D E T1 树上直接贪心,环上for一遍贪心 哇说的简单,码了将近一下午终于码出来了 感觉自己码力/写题策略太糟糕了,先是搞了一个细节太多的写法最后不得不弃疗了,然后第二 ...

  4. [hgoi#2019/3/10]赛后总结

    关于本次hg模拟赛,题目来源于CF1110. t1-无意义运算符(meaning) 题目描述 最大公约数和位运算之间有共同点吗?是时候来研究一下了. 给定一个正整数a,请找到一个闭区间[1,a-1] ...

  5. 「HGOI#2019.4.19省选模拟赛」赛后总结

    t1-Painting 这道题目比较简单,但是我比较弱就只是写了一个链表合并和区间DP. 别人的贪心吊打我的DP,嘤嘤嘤. #include <bits/stdc++.h> #define ...

  6. [hgoi#2019/3/3]赛后总结

    T1--最长公共前缀(lcp) 定义两个字符串S,T 的最长公共前缀lcp(S,T)为最长的字符串R,满足R 既是S 的前缀又是T 的前缀. 给定一个字符串S,下标从1 开始,每次询问给出四个正整数a ...

  7. 2019.8.14 NOIP模拟测试21 反思总结

    模拟测试20的还没改完先咕着 各种细节问题=错失190pts T1大约三分钟搞出了式子,迅速码完,T2写了一半的时候怕最后被卡评测滚去交了,然后右端点没有初始化为n…但是这样还有80pts,而我后来还 ...

  8. 2019.8.3 NOIP模拟测试12 反思总结【P3938 斐波那契,P3939 数颜色,P3940 分组】

    [题解在下面] 早上5:50,Gekoo同学来到机房并表态:“打暴力,打暴力就对了,打出来我就赢了.” 我:深以为然. (这是个伏笔) 据说hzoi的人还差两次考试[现在是一次了]就要重新分配机房,不 ...

  9. 2019.7.29 NOIP模拟测试10 反思总结【T2补全】

    这次意外考得不错…但是并没有太多厉害的地方,因为我只是打满了暴力[还没去推T3] 第一题折腾了一个小时,看了看时间先去写第二题了.第二题尝试了半天还是只写了三十分的暴力,然后看到第三题是期望,本能排斥 ...

随机推荐

  1. OpenStack 与 Rancher

    OpenStack 与 Rancher 融合的新玩法 - Rancher - SegmentFault 思否https://segmentfault.com/a/1190000007965378 Op ...

  2. centos ping www.baidu.com ping: unknown host www.baidu.com

    [root@zabbix ~]# cat /etc/resolv.conf ; generated by /sbin/dhclient-script nameserver 219.141.136.10

  3. PHP单元测试PHPUnit

    配置说明 1.全局安装phpunit命令脚本 1 2 3 4 5 $ wget https://phar.phpunit.de/phpunit-7.0.phar $ chmod +x phpunit- ...

  4. Day 4-3 os & sys模块

    常用方法: import os os.getcwd() # 获取当前程序的工作路径(python解释器的运行路径,不是脚本所在的路径.) os.listdir() # 获取当前程序根目录下的所有文件夹 ...

  5. Web移动端---iPhone X适配(底部栏黑横线)

    一.相信大家有被iPhone X底部黑色横线支配的恐惧 上面我们可以看到,底部的导航栏被一条黑色横线所盖住,那么就很烦.下面我们可以开始进行适配环节 1.首先我们可以用 JS 判断手机环境是不是 iP ...

  6. spring boot中常用的配置文件的重写

    @Configuration public class viewConfigSolver extends WebMvcConfigurerAdapter { /* spring boot 已经自动配置 ...

  7. django migrate报错(提前删除表等)

    python3 manage.py makemigrations python3 manage.py migrate ##报错 改为##更改migrates的状态 python3 manage.py ...

  8. JQ获取URL中是否含有某个字符的话,对页面进行某种操作

    一.//JQ获取URL中是否含有某个字符的话,对页面进行某种操作 例:如果URL中含有xia的字符,就在页面引入一个cssvar str=window.location.href; //获取地址栏UR ...

  9. 1064 - You have an error in your SQL syntax;

    mysql 1064 错误: SQL语法错误,check the manual that corresponds to your MySQL server version for the right ...

  10. Ajax 调用的WCF

    支持ajax 跨域调用的WCF搭建 1.新建一个"ASP.NET空Web应用程序"项目. 2.新建一个“WCF服务(支持ajax)”. 3.修改WCFAjaxService.svc ...