首页 > 其他分享 >Luogu

Luogu

时间:2024-11-11 18:20:41浏览次数:1  
标签:LF psz ch puts Luogu write include

Luogu 比赛记录

【LGR-206-Div.3】洛谷基础赛 #17 & Diligent-OI Round 1

P11274 「Diligent-OI R1 D」DlgtTemplate

周日被同机房大佬叫去写的

因为看着很dp,所以往dp想。

发现从前向后dp很神秘,后效性很大。

于是 唐了15min 想到倒序dp。

设 \(f_{i, j}\) 表示 \([i, n]\) 中选出的需要把前面所选的 \(j\) 个元素的最大值。

\(f_{i, j} \leftarrow \max(f_{i + 1, j - b_i} + a_i, f_{i, j})\)。就很没有后效性。

于是我就开始犯错了。

首先,设 \(psz_i\) 表示 \([1, i]\) 中 \(b_i = 0\) 的个数。

显然对于 \(f_{i, j}\),仅当 \(psz_{i - 1} \ge j\) 时能取到。否则要删去的数会大于 \(j\)。而我首先想的是 \(j < i\) 即可……

其次,我过不了样例 \(4\),在神秘力量的帮助下,我发现,我题目看少了。 题目的有很特殊的地方。

最左边某些点会在逃过删除,而很显然逃过删除的只能是最左边的点。枚举该点,设下标为 \(i\)。

则 \(i\) 后面选择的点的 \(b_i\) 只能等于 \(0\)。否则 \(i\) 会被删。

于是就可以得出答案了。

因为算法是 \(O(n^2)\) 的,所以求方案很好求。

点击查看代码
#ifdef ONLINE_JUDGE
#else
#define FRZ_29
#endif

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <map>
typedef long long LL;

using namespace std;

void read() {}
template<typename T, typename... U> void read(T &x, U &...arg) {
    x = 0; int f = 1; char ch = getchar();
    while (ch > '9' || ch < '0') { if (ch == '-') f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar();
    x *= f; read(arg...);
}

void write() {}
template<typename T> void write(T x) {
    if (x < 0) { putchar('-'); x = -x; }
    if (x > 9) write(x / 10);
    putchar(x % 10 + '0');
}

const int N = 3005;

#define PRINT(x) cout << #x << " = " << x << "\n"
#define LF(i, __l, __r) for (int i = __l; i <= __r; i++)
#define RF(i, __r, __l) for (int i = __r; i >= __l; i--)

int n, a[N], b[N];
LL f[N][N], f1, f2;
int psz[N], cnt, pz[N], p1, p2, p3;
bool vis[N][N];
vector<int> ans1, ans2;

int main() {
#ifdef FRZ_29
    freopen("z_example.in", "r", stdin);
    freopen("z_example.out", "w", stdout);
#endif
    
    read(n);
    LF(i, 1, n) read(a[i]);
    LF(i, 1, n) read(b[i]);
    
    LF(i, 1, n) {
        if (i == 1) b[i] = 0;
        if (b[i] == 0) pz[++cnt] = i;
        psz[i] = psz[i - 1] + (b[i] == 0);
    }

    RF(i, n, 1) {
        LF(j, 0, n) f[i][j] = f[i + 1][j];
        
        LF(j, b[i], n) {
            if (f[i][j] < f[i + 1][j - b[i]] + a[i]) {
                f[i][j] = f[i + 1][j - b[i]] + a[i];
                vis[i][j] = true;
            }
        }
    }

    LF(i, 1, n) {
        LF(j, 0, n) {
            if (psz[i - 1] >= j && f1 < f[i][j]) {
                f1 = f[i][j];
                p1 = i; p2 = j;
            }
        }
    }

    LL sum = 0;
    RF(i, n, 1) {
        if (!b[i]) {
            if (a[i] > 0) sum += a[i];
        } else {
            if (sum + a[i] > f2) {
                f2 = sum + a[i];
                p3 = i;
            }
        }
    }

    if (f1 > f2) {
        LF(i, 1, cnt) {
            if (pz[i] < p1) ans1.push_back(pz[i]);
            else break;
        }

        LF(i, p1, n) {
            if (vis[i][p2]) {
                ans1.push_back(i);
                p2 -= b[i];
            }
        }
        
        write(ans1.size()); puts("");
        for (auto v : ans1) { write(v); putchar(' '); }
        puts(""); write(f1); puts("");
    } else {
        LF(i, 1, n) {
            if (i == p3 || (i > p3 && !b[i] && a[i] > 0)) ans2.push_back(i);
        }

        write(ans2.size()); puts("");
        for (auto v : ans2) { write(v); putchar(' '); }
        puts(""); write(f2); puts("");
    }

    return 0;
}

// START AT 2024 / 11 / 11 12 : 26 : 33

标签:LF,psz,ch,puts,Luogu,write,include
From: https://www.cnblogs.com/FRZ29/p/18540292

相关文章

  • luogu-P3262题解
    简要题意有一棵不超过十层的满二叉树,需要对每个节点进行染色。每个叶子节点会对其颜色相同的祖先节点产生贡献且黑白贡献不同。求最大贡献。题解首先我会暴力!我如果直接暴力枚举每个节点的颜色,复杂度就是\(O(2^{2^n})\)。然后还要算贡献,所以还有一个\(O(2^{n-1}(n-1))\)。然......
  • [luogu1248] 加工生产调度 题解
    考虑\(i\)排在\(j\)前的条件是\(a_i+\max(a_j,b_i)+b_j\lea_j+\max(a_i,b_j)+b_i\),然后发现这一坨东西是皇后游戏中的倒数第三个式子,直接转化为\(\min(a_j,b_i)\ge\min(a_i,b_j)\),然后就按皇后游戏中的排序方法就可以了……#include<bits/stdc++.h>#defineintlonglong......
  • [luogu1248] 加工生产调度 题解
    考虑\(i\)排在\(j\)前的条件是\(a_i+\max(a_j,b_i)+b_j\lea_j+\max(a_i,b_j)+b_i\),然后发现这一坨东西是皇后游戏中的倒数第三个式子,直接转化为\(\min(a_j,b_i)\ge\min(a_i,b_j)\),然后就按皇后游戏中的排序方法就可以了……#include<bits/stdc++.h>#defineintlonglong......
  • [luogu1248] 加工生产调度 题解
    考虑\(i\)排在\(j\)前的条件是\(a_i+\max(a_j,b_i)+b_j\lea_j+\max(a_i,b_j)+b_i\),然后发现这一坨东西是皇后游戏中的倒数第三个式子,直接转化为\(\min(a_j,b_i)\ge\min(a_i,b_j)\),然后就按皇后游戏中的排序方法就可以了……#include<bits/stdc++.h>#defineintlonglong......
  • [luogu2123] 皇后游戏
    那她既然都说到老国王了,那肯定就是贪心了。先声明两个引理:引理1:若\(\max(c,a)<\max(c,b)\)时,定有\(a<b\)。引理2:\(\max(a,b)-a-b=-\min(a,b)\)。证明就不说了,非常好证。考虑\(i,j\)两大臣孰先孰后,假如\(i\)在前面更优,\(x\)表示所有在他们前面的大臣的\(\suma\)......
  • [lnsyoj1801/luoguP2051/AHOI2009] 中国象棋
    题意在\(n\timesm\)大小的棋盘上放无标号棋子,使得任何一行或一列都不多于\(2\)个棋子,求方案数sol计数题,优先考虑dp。由于每行每列棋子不多于两个,所以我们可以计\(f_{i,j,k}\)表示前\(i\)行中,\(j\)列恰好\(1\)个棋子,\(k\)列恰好\(2\)个棋子的方案数。状态转......
  • [lnsyoj1521/luoguP2292] 打鼹鼠
    题意给定\(n\)个点\((x_i,y_i)\)和对应时间\(time_i\),求从任意点开始,每单位时间静止或四向移动,在\(time_i\)时停留的点数的最大值,保证\(time_i\)顺序输入sol线性dp记\(f_i\)表示停留在第\(i\)个点时,点数的最大值,则转移方程为\[f_i=\max_{j=1}^if_j+1(dist_{i,......
  • [luoguP2901] Cow Jogging G
    题意给出一个\(n\)个点\(m\)条边的正权有向图,求从点\(n\)到点\(1\)的前\(k\)短路的距离分别是多少。sol\(k\)短路问题往往使用A*算法(时间复杂度\(O(nk\logn)\))或可持久化可并堆优化最短路树(时间复杂度\(O((n+m)\logm+k\logk)\)),由于本题数据范围较小,可以......
  • [luoguP1456] Monkey King
    题意给出\(n\)个集合\(S_1\cdotsS_n\),\(S_i=\{a_i\}\),每次给出\(x,y\),将第\(x\)和第\(y\)个元素所在的集合的最大值\(\div2\),合并两个集合,然后输出新集合的最大值。sol每次求出两个集合,记录两个集合的最大值并删除,将两个集合与两个最大值除以\(2\)后合并即可。......
  • luoguP6222
    \[\sum_{i=1}^{n}\sum_{j=1}^{n}(i+j)^{t}f(\gcd(i,j))\gcd(i,j)\]\[\sum_{i=1}^{n}\sum_{j=1}^{n}(i+j)^{t}\mu(\gcd(i,j))^{2}\gcd(i,j)\]\[\sum_{k=1}^{n}k^{t+1}\sum_{i=1}^{\lfloor\frac{n}{k}\rfloor}\sum_{j=1}^{\lfloor\frac{n}{k}\rfloor}(......