首页 > 其他分享 >YC339A [ 20240915 CQYC NOIP 模拟赛 T1 ] 演讲(talk)

YC339A [ 20240915 CQYC NOIP 模拟赛 T1 ] 演讲(talk)

时间:2024-09-15 21:54:42浏览次数:9  
标签:NOIP YC339A 地点 len T1 第二种 操作 include define

题意

有 \(n\) 个地点,你可以:

  • 使用 \(\frac{a_i}{len}\) 的代价标记该地点。
  • 使用 \(\frac{b_i}{len}\) 的代价标记该地点并使得 \(len := len + 1\)。
  • 跳过该地点。

你不需要按照顺序标记,问标记 \(m\) 个点的最小代价是多少(可以证明答案是实数)。

\(n \le 500, a_i \le b_i\)。

Sol

注意到一个贪心,就是枚举第二种操作选了多少,然后剩下就贪心选择第一种操作。

这样为什么是错的?因为可以有情况使得一个地点 \(a_i\) 极小而 \(b_i\) 需要选择,这个时候只需要选择 \(a_i\),换成下一个不是很优的 \(b_j\)。

但是注意到这个东西我们可以考虑 \(\texttt{dp}\),依然是枚举第二种操作的数量,设 \(f_{i, j, k}\) 表示前 \(i\) 个地点第一种操作的数量为 \(j\) 第二种操作的数量为 \(k\)。

这样是 \(O(n ^ 4)\) 的,很菜。

考虑一个优化,不难发现最后一次选择的第二种操作之前不会有地点选择第三种操作,也就是被跳过。

于是只需要枚举最后一次的位置就行了,改设为 \(f_{i, j}\) 前 \(i\) 个地点选择了 \(j\) 个第二种操作。

复杂度 \(O(n ^ 3)\)。

Code

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <array>
#define pii pair <int, int>
#define db double
using namespace std;
#ifdef ONLINE_JUDGE

#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
char buf[1 << 23], *p1 = buf, *p2 = buf, ubuf[1 << 23], *u = ubuf;

#endif
int read() {
    int p = 0, flg = 1;
    char c = getchar();
    while (c < '0' || c > '9') {
        if (c == '-') flg = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9') {
        p = p * 10 + c - '0';
        c = getchar();
    }
    return p * flg;
}
void write(int x) {
    if (x < 0) {
        x = -x;
        putchar('-');
    }
    if (x > 9) {
        write(x / 10);
    }
    putchar(x % 10 + '0');
}
bool _stmer;

#define fi first
#define se second

const int N = 505, inf = 2e9;

array <array <double, N>, N> f;
array <pii, N> s;

array <array <pii, N>, N> g;

bool _edmer;
int main() {
    cerr << (&_stmer - &_edmer) / 1024.0 / 1024.0 << "MB\n";
#ifndef cxqghzj
    freopen("talk.in", "r", stdin);
    freopen("talk.out", "w", stdout);
#endif
    int n = read(), m = read();
    for (int i = 1; i <= n; i++) {
        s[i].fi = read(), s[i].se = read();
        if (!~s[i].se) s[i].se = inf;
    }
    sort(s.begin() + 1, s.begin() + 1 + n, [](pii x, pii y) {
        return x.se < y.se;
    });
    for (int i = 0; i <= n; i++)
        g[i] = s, sort(g[i].begin() + 1 + i, g[i].begin() + 1 + n);
#define upd(x, y) (x = min(x, y))
    db ans = 0;
    for (int i = 1; i <= m; i++)
        ans += g[0][i].fi;
    for (int l = 1; l <= m; l++) {
        for (int i = 0; i <= n; i++)
            f[i].fill(4e18);
        f[0][0] = 0;
        for (int i = 1; i <= n; i++) {
            for (int j = 0; j <= l; j++) {
                upd(f[i][j], f[i - 1][j] + (db)s[i].fi / (l + 1));
                if (j) upd(f[i][j], f[i - 1][j - 1] + (db)s[i].se / j);
            }
            if (i < l) continue;
            db sum = 0;
            for (int j = i + 1; j <= m; j++)
                sum += (db)g[i][j].fi / (l + 1);
            ans = min(ans, sum + f[i][l]);
        }
    }
    printf("%.6lf\n", ans);
    return 0;
}

标签:NOIP,YC339A,地点,len,T1,第二种,操作,include,define
From: https://www.cnblogs.com/cxqghzj/p/18415724

相关文章

  • 正睿OI 24noip十连测day3总结
    A.茵蒂克丝题意:给定两个序列\(a,b\),每次询问\([l,r]\)内选出一个长度不小于\(k\)的子区间\([l',r']\),使得\(\frac{\sum_{i=l'}^{r'}a_i}{\sum_{i=l'}^{r'}b_i}\)尽可能大。其中\(k\)为定值。\(n,q≤1e6,k≤20\)题解:有结论,区间长度一定小于\(2\timesk\),这是......
  • 【题解】【动态规划】—— [NOIP2006 普及组] 开心的金明
    【题解】【动态规划】——[NOIP2006普及组]开心的金明[NOIP2006普及组]开心的金明题目描述输入格式输出格式输入输出样例输入#1输出#1提示1.题意解析2.AC代码2.1.二维d......
  • 【题解】【模拟】—— [NOIP2008 普及组] ISBN 号码
    【题解】【模拟】——[NOIP2008普及组]ISBN号码[NOIP2008普及组]ISBN号码题目描述输入格式输出格式输入输出样例输入#1输出#1输入#2输出#2提示1.思路解析2.AC代码[NOIP2008普及组]ISBN号码通往洛谷的传送门题目描述每一本正式出版的图书都有一个I......
  • 【题解】—— [NOIP2011 普及组] 数字反转
    【题解】——[NOIP2011普及组]数字反转[NOIP2011普及组]数字反转题目描述输入格式输出格式输入输出样例输入#1输出#1输入#2输出#2提示1.思路解析2.AC代码[NOIP2011普及组]数字反转通往洛谷的传送门题目描述给定一个整数......
  • 【题解】【数组】—— [NOIP2005 普及组] 校门外的树
    【题解】【数组】——[NOIP2005普及组]校门外的树[NOIP2005普及组]校门外的树题目描述输入格式输出格式输入输出样例输入#1输出#1提示1.题意解析2.AC代码[NOIP2005普及组]校门外的树通往洛谷的传送门题目描述某校大门外长度为......
  • ZR24NOIP1B. 数数
    ZR24NOIP1B.数数给你一个长度为\(n\le1600\)的二进制数,其中某些位未知,是?。问?的所有取值得到的\(x\),\([0,x-1]\)中不含长度为\(k\le20\)的回文串的数字(含前导\(0\))的个数的和。首先显然是数位DP。考虑从高位枚举到低位,假设没有?,状态记位数\((1600)\)和是否顶......
  • 2024.9.15 NOIP2024#6模拟赛
    不怎么模拟的模拟赛。比赛界面吐槽以IOI赛制来模拟OI赛事,\(jzyz\)真难绷。暴力有点难打,纯暴力(全排列)等拿的分少。不会写(我太蒻了)。\(T4\)暴力让我怒砍\(\textcolor{#ecdb44}{65pts}\)。文件\(IO\)是开考后加的。跟新高二打打了个倒数,压迫感略强。看了\(1h\)......
  • NOIP 模拟赛
    警示:看到一道做过的题不要着急上头去写,写炸了心态就崩了。T1题意:有\(n\)个人,每个人有经验\(w_i\)、薪水\(s_i\)、意愿\(p_i\)三个属性。要选出\(2k\)个人组成\(k\)组,每组两个人。每个组内一人做组长,一人做组员。要求组长经验\(\ge\)组员。每个人可能有三种意愿:组......
  • 南沙C++noip老师解一本通题: 1360:奇怪的电梯(lift)
    ​【题目描述】大楼的每一层楼都可以停电梯,而且第i层楼(1≤i≤N)上有一个数字Ki(0≤=Ki≤=N)。电梯只有四个按钮:开,关,上,下。上下的层数等于当前楼层上的那个数字。当然,如果不能满足要求,相应的按钮就会失灵。例如:33125代表了Ki(K1=3,K2=3,……),从一楼开始。在一楼,按“上”可以到4......
  • 2024 Noip 做题记录(一)
    \(\text{ByDaiRuiChen007}\)Round#1-20240909A.[P10997]ColorProblemLink题目大意你有\(n\)行\(m\)列的一个矩阵,第\(i\)行第\(j\)列的格子(记作\((i,j)\))上写有一个整数\(a_{i,j}\),你可以把所有格子染上红、橙、黄、绿四种颜色之一。红色格子的上方只......