最新文章

[CF5E]Bindian Signalizing 题解

[CF5E]Bindian Signalizing 题解

题目地址:Codeforces:Problem – 5E – Co 

[BZOJ4318]OSU! 题解

[BZOJ4318]OSU! 题解

题目地址:BZOJ:Problem 4318. — OSU! 题目描述 osu 

[CF5D]Follow Traffic Rules 题解

[CF5D]Follow Traffic Rules 题解

题目地址:Codeforces:Problem – 5D – Codeforces、洛谷:CF5D Follow Traffic Rules – 洛谷 | 计算机科学教育新生态

题目描述

Everybody knows that the capital of Berland is connected to Bercouver (the Olympic capital) by a direct road. To improve the road’s traffic capacity, there was placed just one traffic sign, limiting the maximum speed. Traffic signs in Berland are a bit peculiar, because they limit the speed only at that point on the road where they are placed. Right after passing the sign it is allowed to drive at any speed.

It is known that the car of an average Berland citizen has the acceleration (deceleration) speed of a km/h2, and has maximum speed of v km/h. The road has the length of l km, and the speed sign, limiting the speed to w km/h, is placed d km (1 ≤ d < l) away from the capital of Berland. The car has a zero speed at the beginning of the journey. Find the minimum time that an average Berland citizen will need to get from the capital to Bercouver, if he drives at the optimal speed.

The car can enter Bercouver at any speed.

题意简述

你驾驶一辆速度最高为$v$、加速度(加减速)为$a$的汽车,在一条长为$l$的道路上行驶,在距离出发点$d$距离的位置上有一个限速标志,需要以不超过$w$的速度通过它,求不超过限速从起点到终点的最短时间。

输入输出格式

输入格式:
The first line of the input file contains two integer numbers a and v (1 ≤ a, v ≤ 10000). The second line contains three integer numbers l, d and w (2 ≤ l ≤ 10000; 1 ≤ d < l; 1 ≤ w ≤ 10000).

输出格式:
Print the answer with at least five digits after the decimal point.

输入输出样例

输入样例#1:

1 1
2 1 3

输出样例#1:

2.500000000000

输入样例#2:

5 70
200 170 40

输出样例#2:

8.965874696353

题解

高中物理题?我都不知道怎么给这个题加Tag。

首先你需要熟悉这么几个有关匀变速运动的公式:
x-t关系:$x = v_0t + \frac{1}{2} at^2$
x-v关系:$v^2 – v_0^2 = 2ax$
平均速度关系:$x = \frac{v_0 + v}{2} t, t = \frac{v – v_0}{a}$

然后,分情况讨论解决这个问题:

  1. 以加速度$a$加速也无法在$d$距离内加速到$w$速度,或者$w \geq v$怎么样也无法超过限速的情况下,只需要全程加速+匀速即可;
  2. 不满足1的情况即是$d$距离内可以加速到$w$的情况,此时更优的方案是在$d$以前先加速后减速,然后在$d$以后加速+匀速。分加速+减速和加速+匀速$v$+减速两种情况讨论即可。

详细的公式在题解思路里就不写出来了,可以参考代码中应用公式的情况。

代码

// Code by KSkun, 2019/7
#include <cstdio>
#include <cctype>

#include <algorithm>

typedef long long LL;

inline char fgc() {
    static char buf[100000], * p1 = buf, * p2 = buf;
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2)
        ? EOF : *p1++;
}

inline LL readint() {
    LL res = 0, neg = 1; char c = fgc();
    for (; !isdigit(c); c = fgc()) if (c == '-') neg = -1;
    for (; isdigit(c); c = fgc()) res = res * 10 + c - '0';
    return res * neg;
}

inline char readsingle() {
    char c;
    while (!isgraph(c = fgc())) {}
    return c;
}

int a, v, l, d, w;

int main() {
    a = readint(); v = readint();
    l = readint(); d = readint(); w = readint();
    double t1 = double(w) / a, t2 = double(v) / a, t3 = double(v - w) / a,
        s1 = w * t1 / 2, s2 = v * t2 / 2, s3 = (w + v) * t3 / 2;
    double ans = 0;
    if(w >= v || s1 >= d) {
        if(s2 >= l) ans += sqrt(2.0 * l / a);
        else {
            ans += t2;
            ans += double(l - s2) / v;
        }
    } else {
        // before d
        if(s2 + s3 <= d) {
            ans += t2 + t3;
            ans += double(d - s2 - s3) / v;
        } else {
            double v0 = sqrt((d - s1) * a + w * w);
            ans += v0 / a + (v0 - w) / a;
        }
        // after d
        if(s3 <= l - d) {
            ans += t3 + (l - d - s3) / v;
        } else {
            double v1 = sqrt(2 * a * (l - d) + w * w);
            ans += (v1 - w) / a;
        }
    }
    printf("%.5lf", ans);
    return 0;
}
[CF5C]Longest Regular Bracket Sequence 题解

[CF5C]Longest Regular Bracket Sequence 题解

题目地址:Codeforces:Problem – 5C – Co 

[NewGeneration]LQZ的OI复健记录

[NewGeneration]LQZ的OI复健记录

按照AC顺序如下: 1.P1002过河卒 2.P1125笨小猴一遍过 3.P1003铺地毯 

[CF4D]Mysterious Present 题解

[CF4D]Mysterious Present 题解

题目地址:Codeforces:Problem – 4D – Codeforces、洛谷:CF4D Mysterious Present – 洛谷 | 计算机科学教育新生态

题目描述

Peter decided to wish happy birthday to his friend from Australia and send him a card. To make his present more mysterious, he decided to make a chain. Chain here is such a sequence of envelopes A = {a1,  a2,  …,  an}, where the width and the height of the i-th envelope is strictly higher than the width and the height of the (i  -  1)-th envelope respectively. Chain size is the number of envelopes in the chain.

Peter wants to make the chain of the maximum size from the envelopes he has, the chain should be such, that he’ll be able to put a card into it. The card fits into the chain if its width and height is lower than the width and the height of the smallest envelope in the chain respectively. It’s forbidden to turn the card and the envelopes.

Peter has very many envelopes and very little time, this hard task is entrusted to you.

题意简述

给定$n$个矩形,长宽分别为$w_i, h_i$。定义矩形的严格递增序列为一个序列$A = \{a_1, a_2, a_3, \dots, a_m\}$满足$w_{a_1} < w_{a_2} < w_{a_3} < \cdots < w_{a_m}, h_{a_1} < h_{a_2} < h_{a_3} < \cdots < h_{a_m}$。请从给定矩形中选出满足$w_i > w, h_i > h$的一些矩形,组成一个最长的严格递增序列。如果找不出任何符合条件的序列,则输出0。

输入输出格式

输入格式:
The first line contains integers n, w, h (1  ≤ n ≤ 5000, 1 ≤ w,  h  ≤ 10^6) — amount of envelopes Peter has, the card width and height respectively. Then there follow n lines, each of them contains two integer numbers wi and hi — width and height of the i-th envelope (1 ≤ wi,  hi ≤ 10^6).

输出格式:
In the first line print the maximum chain size. In the second line print the numbers of the envelopes (separated by space), forming the required chain, starting with the number of the smallest envelope. Remember, please, that the card should fit into the smallest envelope. If the chain of maximum size is not unique, print any of the answers.

If the card does not fit into any of the envelopes, print number 0 in the single line.

输入输出样例

输入样例#1:

2 1 1
2 2
2 2

输出样例#1:

1
1 

输入样例#2:

3 3 3
5 4
12 11
9 8

输出样例#2:

3
1 3 2 

题解

一眼过去,LIS的即视感,而且数据范围提示$O(n^2)$的普通LIS能跑过,那应该就是它了。
考虑到严格递增矩形序列一定是长宽都递增,那么按长为第一关键字,宽为第二关键字排序后直接在新序列上做LIS即可。

LIS的$O(n^2)$DP算法如下:
对于每一个位置$i$,向前找满足$w_j < w_i, h_j < h_i$的位置,并取$dp(j)$最大的位置,完成转移,即
$$ dp(i) = \max_{w_j < w_i, h_j < h_i} \{dp(j)\} + 1 $$

代码

// Code by KSkun, 2019/6
#include <cstdio>
#include <cctype>

#include <algorithm>
#include <vector>

typedef long long LL;

inline char fgc() {
    static char buf[100000], *p1 = buf, *p2 = buf;
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2)
        ? EOF : *p1++;
}

inline LL readint() {
    LL res = 0, neg = 1; char c = fgc();
    for(; !isdigit(c); c = fgc()) if(c == '-') neg = -1;
    for(; isdigit(c); c = fgc()) res = res * 10 + c - '0';
    return res * neg;
}

inline char readsingle() {
    char c;
    while(!isgraph(c = fgc())) {}
    return c;
}

const int MAXN = 5005;

int n, w, h, dp[MAXN], pre[MAXN];
std::vector<int> ans;

struct Node {
    int w, h, no;
    bool operator<(const Node &rhs) const {
        return w == rhs.w ? h < rhs.h : w < rhs.w;
    }
} env[MAXN];

int main() {
    n = readint(); w = readint(); h = readint();
    for(int i = 1; i <= n; i++) {
        env[i].w = readint(); env[i].h = readint();
        env[i].no = i;
    }
    std::sort(env + 1, env + n + 1);
    for(int i = 1; i <= n; i++) {
        if(env[i].w <= w || env[i].h <= h) continue;
        int mxn = 0;
        for(int j = 1; j < i; j++) {
            if(env[j].w <= w || env[j].h <= h) continue;
            if(env[i].w > env[j].w && env[i].h > env[j].h && dp[j] > dp[mxn]) {
                mxn = j;
            }
        }
        dp[i] = dp[mxn] + 1; pre[i] = mxn;
    }
    int mxn = 0;
    for(int i = 1; i <= n; i++) {
        if(env[i].w <= w || env[i].h <= h) continue;
        if(dp[i] > dp[mxn]) mxn = i;
    }
    if(mxn == 0) {
        puts("0"); return 0;
    }
    printf("%d\n", dp[mxn]);
    int t = mxn;
    while(t != 0) {
        ans.push_back(env[t].no);
        t = pre[t];
    }
    std::reverse(ans.begin(), ans.end());
    for(int i = 0; i < ans.size(); i++) {
        printf("%d ", ans[i]);
    }
    return 0;
}
[CF3D]Least Cost Bracket Sequence 题解

[CF3D]Least Cost Bracket Sequence 题解

题目地址:Codeforces:Problem – 3D – Co 

[CF3C]Tic-tac-toe 题解

[CF3C]Tic-tac-toe 题解

题目地址:Codeforces:Problem – 3C – Co 

[CF3B]Lorry 题解

[CF3B]Lorry 题解

题目地址:Codeforces:Problem – 3B – Codeforces、洛谷:CF3B Lorry – 洛谷 | 计算机科学教育新生态

题目描述

A group of tourists is going to kayak and catamaran tour. A rented lorry has arrived to the boat depot to take kayaks and catamarans to the point of departure. It’s known that all kayaks are of the same size (and each of them occupies the space of 1 cubic metre), and all catamarans are of the same size, but two times bigger than kayaks (and occupy the space of 2 cubic metres).

Each waterborne vehicle has a particular carrying capacity, and it should be noted that waterborne vehicles that look the same can have different carrying capacities. Knowing the truck body volume and the list of waterborne vehicles in the boat depot (for each one its type and carrying capacity are known), find out such set of vehicles that can be taken in the lorry, and that has the maximum total carrying capacity. The truck body volume of the lorry can be used effectively, that is to say you can always put into the lorry a waterborne vehicle that occupies the space not exceeding the free space left in the truck body.

题意简述

有一辆能够装载容量为$v$的货车,共有$n$个货物待装。货物分为两种类型,类型1所占容量为1,类型2所占容量为2,同种类型的货物的价值可能不同。求货车最多可以装载货物的最大价值之和。

输入输出格式

输入格式:
The first line contains a pair of integer numbers n and v (1 ≤ n ≤ 10^5; 1 ≤ v ≤ 10^9), where n is the number of waterborne vehicles in the boat depot, and v is the truck body volume of the lorry in cubic metres. The following n lines contain the information about the waterborne vehicles, that is a pair of numbers ti, pi (1 ≤ ti ≤ 2; 1 ≤ pi ≤ 10^4), where ti is the vehicle type (1 – a kayak, 2 – a catamaran), and pi is its carrying capacity. The waterborne vehicles are enumerated in order of their appearance in the input file.

输出格式:
In the first line print the maximum possible carrying capacity of the set. In the second line print a string consisting of the numbers of the vehicles that make the optimal set. If the answer is not unique, print any of them.

输入输出样例

输入样例#1:

3 2
1 2
2 7
1 3

输出样例#1:

7
2

题解

首先看到这个题就有一种强烈的直觉,即按单位容量的价值(即所谓的“性价比”)排序,先从大到小贪心地装,此时会遇到三种情况:货物的总占用容量小于货车容量,或者货车容量刚好用完,或者还剩1没有用。
对于第一种情况,直接全装进去就完事了。
对于第二种情况,直接按贪心的方案输出即可,因为根据贪心的思路,用单位价值较低的货物替换只会让方案变得更劣。
对于第三种情况,有两种选择:用未装进去的占容量为1的货物填这个空,或者把前面的某个占容量为1的货物替换为一个占容量为2的货物。第一个选择中,填空的货物肯定是未装之中价值最大的那个,而第二个选择中,肯定是用价值最大的2货物替换价值最小的1货物,这些都可以贪心地做。判断一下哪种选择更优即可。
思路比较好想,不过细节比较多,代码稍微有点难度。

代码

// Code by KSkun, 2019/6
#include <cstdio>
#include <cctype>

#include <algorithm>

typedef long long LL;

inline char fgc() {
    static char buf[100000], *p1 = buf, *p2 = buf;
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2)
        ? EOF : *p1++;
}

inline LL readint() {
    LL res = 0, neg = 1; char c = fgc();
    for(; !isdigit(c); c = fgc()) if(c == '-') neg = -1;
    for(; isdigit(c); c = fgc()) res = res * 10 + c - '0';
    return res * neg;
}

inline char readsingle() {
    char c;
    while(!isgraph(c = fgc())) {}
    return c;
}

const int MAXN = 100005;

int n, v;

struct Node {
    int no, t, p;
    bool operator>(const Node &rhs) const {
        return double(p) / t > double(rhs.p) / rhs.t;
    }
} a[MAXN];

int main() {
    n = readint(); v = readint();
    for(int i = 1; i <= n; i++) {
        a[i].t = readint();
        a[i].p = readint();
        a[i].no = i;
    }
    std::sort(a + 1, a + n + 1, std::greater<Node>());
    int mn1 = 1e9, mn1n = 0, sum = 0, i;
    for(i = 1; i <= n; i++) {
        if(v < a[i].t) break;
        if(a[i].t == 1 && a[i].p < mn1) {
            mn1 = a[i].p; mn1n = i;
        }
        v -= a[i].t;
        sum += a[i].p;
    }
    int mx1 = 0, mx1n = 0, mx2 = 0, mx2n = 0;
    for(int j = i; j <= n; j++) {
        if(a[j].t == 1 && a[j].p > mx1) {
            mx1 = a[j].p; mx1n = j;
        }
        if(a[j].t == 2 && a[j].p > mx2) {
            mx2 = a[j].p; mx2n = j;
        }
    }
    if(v == 0 || (i == n && v >= a[n].t)) {
        printf("%d\n", sum);
        for(int j = 1; j < i; j++) printf("%d ", a[j].no);
    } else {
        int ans1 = 0, ans2 = 0;
        if(mx1 != 0) ans1 = sum + mx1;
        if(mx2 != 0) ans2 = sum - mn1 + mx2;
        int ans = std::max(ans1, ans2);
        ans = std::max(ans, sum);
        printf("%d\n", ans);
        for(int j = 1; j < i; j++) {
            if(ans != sum && ans != ans1 && ans == ans2 && j == mn1n) continue;
            printf("%d ", a[j].no);
        }
        if(ans != sum && ans == ans1) printf("%d ", a[mx1n].no);
        if(ans != sum && ans != ans1 && ans == ans2) printf("%d ", a[mx2n].no);
    }
    return 0;
}
[CF2C]Commentator problem 题解

[CF2C]Commentator problem 题解

题目地址:Codeforces:Problem – 2C – Co