zoukankan      html  css  js  c++  java
  • 所谓的日常 #10

    div.2

    CodeForces 546B Soldier and Badges

    给定n(<= 3000)个整数Ai,有一种操作:给某个数加1。问最少操作几次,使得n个数都不一样。

    考虑这样一个问题:已知一个数组B,用上面的操作,把A变成B的最小代价怎么算。

    一个最优的方法是,把A中最小的数变成B中最小的数,把A中次小的数变成B中次小的数...把A中最大的数变成B中最大的数。

    所以做法就出来了。先把A数组排序,然后把A[i]变成max(A[i],B[i - 1] + 1)即可。(因为同样要保证变化完后B数组递增)

     1 #include <stdio.h>
     2 #include <algorithm>
     3 
     4 int A[3000];
     5 int n;
     6 
     7 int main() {
     8     scanf("%d",&n);
     9     for (int i = 0; i < n; ++ i) {
    10         scanf("%d",A + i);
    11     }
    12     std::sort(A,A + n);
    13     int answer = 0;
    14     for (int i = 1; i < n; ++ i) {
    15         if (A[i] <= A[i - 1]) {
    16             answer += A[i - 1] + 1 - A[i];
    17             A[i] = A[i - 1] + 1;
    18         }
    19     }
    20     printf("%d
    ",answer);
    21 }
    View Code

    div.1

    CodeForces 461B Appleman and Tree

    给定一棵n(<=1e5)个节点的树,每个节点有颜色(黑或白),让你删掉一些边使得剩下的每个连通块内都恰好只有1个黑点。问删边的方案数。

    那么就dp(u,c)表示节点u的子数,与u关联的连通块有/无黑点的状态是c,的方案数。

    然后就是一个树dp啦。

     1 #include <bits/stdc++.h>
     2 
     3 const int MOD = (int)1e9 + 7;
     4 const int N = 100000 + 5;
     5 std::vector<int> edges[N];
     6 int color[N];
     7 int n;
     8 int dp[N][2];
     9 
    10 inline void add(int &a,int b) {
    11     a += b;
    12     if (a >= MOD) a -= MOD;
    13 }
    14 
    15 void dfs(int u) {
    16     if (color[u] == 1) {
    17         dp[u][1] = 1;
    18         dp[u][0] = 0;
    19     } else {
    20         dp[u][0] = 1;
    21         dp[u][1] = 0;
    22     }
    23     for (int i = 0; i < edges[u].size(); ++ i) {
    24         int v = edges[u][i];
    25         dfs(v);
    26         int tmp[2] = {};
    27         for (int a = 0; a < 2; ++ a) {
    28             for (int b = 0; b < 2; ++ b) {
    29                 add(tmp[a | b],dp[u][a] * 1ll * dp[v][b] % MOD);
    30                 if (a == 0 && b == 1) {
    31                     add(tmp[0],dp[u][a] * 1ll * dp[v][b] % MOD);
    32                 }
    33             }
    34         }
    35         dp[u][0] = tmp[0];
    36         dp[u][1] = tmp[1];
    37     }
    38 
    39 }
    40 
    41 int work() {
    42     dfs(0);
    43     return dp[0][1];
    44 }
    45 
    46 int main() {
    47     scanf("%d",&n);
    48     for (int i = 1; i < n; ++ i) {
    49         int x;
    50         scanf("%d",&x);
    51         edges[x].push_back(i);
    52     }
    53     for (int i = 0; i < n; ++ i) {
    54         scanf("%d",color + i);
    55     }
    56     printf("%d
    ",work());
    57 }
    View Code
  • 相关阅读:
    【洛谷P2967】【USACO 2009 Dec】电子游戏 Video Game Troubles
    2021-09-11 刷题 39. 组合总和
    2021-09-10 刷题 160. 相交链表
    2021-09-09 刷题 141. 环形链表
    2021-09-08 刷题 20. 有效的括号
    2021-09-07 刷题 119杨辉三角2
    2021-08-01 刷题 合并两个有序链表
    2021-07-31 leetcode刷题记录 两数之和
    根据需要数据库的内容,封装增删改查的sql函数
    QT 对XML 文件进行增删改查
  • 原文地址:https://www.cnblogs.com/zstuACM/p/5111269.html
Copyright © 2011-2022 走看看