2019洛谷csp冲刺模拟赛

难题做不动就去翻去年的洛谷csp题做,实在是水啊~

第一次

(A)

(dp_{i, j})表示使用(i)个色子得到点数为(j)的概率,这样求出(dp_x)和(dp_y)两个(dp)数组后就可以枚举(x)个色子得到的点数,(y)个色子得到的点数是一个前缀,枚举即可。

#include 
#include 
#include 
using namespace std;
int x, y;
double dp[1050][6050], sum[6050];
int main()
{
    scanf("%d%d", &x, &y);
    for (int i = 1; i <= 6; i++) dp[1][i] = 1.0 / 6.0;
    for (int i = 1; i <= (max(x, y)) - 1; i++)
        for (int j = 1; j <= 6 * i; j++)
            for (int k = 1; k <= 6; k++)
                dp[i + 1][j + k] = dp[i + 1][j + k] + dp[i][j] / 6.0;
    double ans = 0, sum = 0;
    for (int i = 0; i <= x * 6; i++)
        ans += sum * dp[x][i], sum += dp[y][i];
    printf("%.2lf", ans * 100.0); putchar('%');
    return 0;
}

(B)

显然最后每个人都会到某个人站的地方集合。

那么先按每个人站的地方排序,从左往右枚举集合的位置,发现这个位置之前的人距离会增加,之后的人的距离会减少,转移是(O(1))的。

所以瓶颈在于排序,时间复杂度(O(n))。

#include 
#include 
#include 
#include 
using namespace std;
#define ll long long
const int N = 1000000;
const ll INF = 999999999999999999;
int a[N + 50], b[N + 50], n;
ll sumb[N + 50], sufb[N + 50];
struct Node
{
    int a, b;
} dl[N + 50];
void Read(int &x)
{
    x = 0; int p = 0; char st = getchar();
    while (st  '9') p = (st == '-'), st = getchar();
    while (st >= '0' && st <= '9') x = (x << 1) + (x << 3) + st - '0', st = getchar();
    x = p ? -x : x;
    return;
}
ll Abs(ll x)
{
    return x < 0 ? -x : x;
}
int Cmp(Node a, Node b)
{
    return a.a < b.a;
}
int main()
{
    Read(n);
    for (int i = 1; i <= n; i++) Read(dl[i].a);
    for (int i = 1; i <= n; i++) Read(dl[i].b);
    ll ans = INF, tmp = 0;
    sort(dl + 1, dl + n + 1, Cmp);
    for (int i = 1; i <= n; i++) sumb[i] = sumb[i - 1] + dl[i].b;
    for (int i = n; i >= 1; i--) sufb[i] = sufb[i + 1] + dl[i].b;
    for (int i = 1; i <= n; i++) tmp = tmp + 1LL * Abs(dl[i].a - dl[1].a) * dl[i].b;
    ans = tmp; 
    for (int i = 2; i <= n; i++)
    {
        tmp = tmp + 1LL * sumb[i - 1] * Abs(dl[i].a - dl[i - 1].a) - 1LL * sufb[i] * Abs(dl[i].a - dl[i - 1].a);
        ans = min(ans, tmp);
    }
    printf("%lld", ans);
    return 0;
}

(C)

对于一段函数,最大值最小值已知的情况下将这段函数拟合到(min + (max - min) / 2)是最优的。

所以问题转化为将数列分成一些段使得每段的极差尽可能小。

二分最小极差判断可行性。

发现判断可行性可以用倍增实现,注意这里倍增时不能算出总共需要的段数,而是段数大于给定段数就要退出。

#include 
#include 
#include 
#include 
using namespace std;
const int N = 1000000; 
int n, x[N + 50], y[N + 50], stmin[25][N + 50], stmax[25][N + 50], maxx;
void Read(int &x)
{
    x = 0; int p = 0; char st = getchar();
    while (st  '9') p = (st == '-'), st = getchar();
    while (st >= '0' && st <= '9') x = (x << 1) + (x << 3) + st - '0', st = getchar();
    x = p ? -x : x;
    return;
}
void Prework()
{
    maxx = 21;
    for (int j = 1; j <= maxx; j++)
        for (int i = 1; i + (1 << j) - 1 <= n; i++)
            stmin[j][i] = min(stmin[j - 1][i], stmin[j - 1][i + (1 << (j - 1))]),
            stmax[j][i] = max(stmax[j - 1][i], stmax[j - 1][i + (1 << (j - 1))]);
    return;
}
bool Check(int d, int m)
{
//    cout << d << endl;
    int l = 1, i;
    for (int i = 0; i < m && l <= n; i++)
    {
        int tmpmax = -1, tmpmin = 1000000001, r = l;
        for (int j = maxx; j >= 0; j--)
            if (r + (1 << j) - 1 <= n)
                if (max(tmpmax, stmax[j][r]) - min(tmpmin, stmin[j][r]) <= d)
                    tmpmin = min(tmpmin, stmin[j][r]), tmpmax = max(tmpmax, stmax[j][r]), r += (1 << j);
    //    cout << l - 1 << " " ;
        l = r;
    }
//    cout << endl;
    return l == n + 1;
}
void Print(int x)
{
    if (x > 9) Print(x / 10);
    putchar(x % 10 + '0');
    return;
}
int main()
{
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) scanf("%*d%d", &stmin[0][i]), stmax[0][i] = stmin[0][i];
    Prework();
    int t, m;
    scanf("%d", &t);
    while (t--)
    {
        scanf("%d", &m);
        int l = 0, r = 1000000001;
        while (l < r)
        {
            int mid = (l + r) >> 1;
            if (Check(mid, m)) r = mid;
            else l = mid + 1; 
        }
        if (l % 2) printf("%d.5\n", l/2);
        else printf("%d\n", l/2);
    }
    return 0;
}
全部评论

相关推荐

牛客535137607号:一定是神人ezi干的好事!😡
点赞 评论 收藏
分享
Java抽象带篮子:可以看看我的置顶帖子,里面写了技术栈怎么描述
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务