• 暑假第二十测


    题解:

    第一题:

    这道题最先想到的就是贪心,但是纯贪心明显是不对的,
    如 2 2 1 3 3 贪心结果为2 2 (133)但实际是2 (21) 3 3 。
    所以这样是不对的。
    那要怎么做呢.....考虑用dp.........
    阶段应该是明显的就是第几个数,我们还是要用到贪心的思想,
    就是保证在最后面的合起来的数尽可能的小
    我们用f[i]表示到第i这个数的最多的组数。
    b[i]表示从1到i的所有数的和(很明显如果合并从k到i那么合并后的数就是b[i]-b[k]);
    s[i]表示到第i这个阶段的最后一个数的大小。
    所以转移方程就是:f[i]=max(f[k]+1); (b[i]-b[k]>=s[k])
    s[i]=b[i]-b[k];

    #include<bits/stdc++.h>
    using namespace std;
    const int inf = 1e8;
    const int M = 5005;
    int dp[M], tot;
    long long res[M], h[M], sum[M];
    int main(){
        freopen("tower.in","r",stdin);
        freopen("tower.out","w",stdout);
        int n;
        scanf("%d", &n);
        for(int i = 1; i <= n; i++)scanf("%I64d", &h[i]), sum[i] = sum[i - 1] + h[i];
        for(int i = 1; i <= n; i++)
            for(int j = 0; j < i; j++){
                if(res[j] <= sum[i] - sum[j]){
                    if(dp[j] + 1 > dp[i])dp[i] = dp[j] + 1, res[i] = sum[i] - sum[j];
                    else if(dp[j] + 1 == dp[i])res[i] = min(sum[i] - sum[j], res[i]);
                }
            }
        printf("%d
    ",n - dp[n]);
    }
    View Code

    第二题:

    动态规划,定义f[i][j]代表在i时间,能力值为j的最多工作次数。

    对应最后三种选择:

    ①不作为 f[i][j]=f[i-1][j],

    ②上课 f[i][j]=f[上课前一个时刻][任意],

    ③做工作 f[i][j]=f[i-po[j]][j]+1 (po[j]为能力值<=j的工作一次的最短用时)。

    对于②可以在预处理出ke[i][j]在i时刻结束,能力值达到j的课程的最晚开始时间。dp过程中处理出g[i]=max{f[i][j]}。

    g[t]即为答案。

    #include<bits/stdc++.h>
    using namespace std;
    const int inf = 1e8;
    const int M = 10005;
    int cl[M], clt[M], mt[M], dp[M][205];
    struct node{int c, d;}p[M];
    /*bool cmp1(node a, node b){
        return a.c + a.d < b.c + b.d;
    }*/
    bool cmp2(node a, node b){
        return a.c < b.c;
    }
    
    int main(){
        freopen("wrk.in","r",stdin);
        freopen("wrk.out","w",stdout);
        int T, S, N, A = 0, ans = 0;
        int m, l, a;
        scanf("%d%d%d", &T, &S, &N);
        for(int i = 1; i <= S; i++){
            scanf("%d%d%d", &m, &l, &a);
            cl[m] = a, clt[m] = l;
            //cls[a].push_back((node){m, l});
            A = max(A, a);
        }
        /*for(int a = 1; a <= A; a++)
            if(cls[a].size() > 1)sort(cls[a].begin(), cls[a].end(), cmp1);
        */
        for(int i = 1; i <= N; i++){
            scanf("%d%d", &p[i].c, &p[i].d);
        }    
        sort(p + 1, p + 1 + N, cmp2);
        memset(mt, 127, sizeof(mt));
        for(int i = 1; i <= N; i++){
            if(p[i].c != p[i - 1].c){
                for(int j = p[i - 1].c + 1; j <= p[i].c; j++)mt[j] = mt[p[i - 1].c];
            }
            mt[p[i].c] = min(mt[p[i].c], p[i].d);
        }
        for(int j = p[N].c + 1; j <= A; j++)mt[j] = mt[p[N].c];
        memset(dp, -1, sizeof(dp));
        dp[0][1] = 0;
        for(int t = 0; t <= T; t++){
            for(int p = 1; p <= A; p++){
                if(dp[t][p] == -1)continue;
                dp[t + 1][p] = max(dp[t + 1][p], dp[t][p]);
                if(mt[p] < inf && t + mt[p] <= T)dp[t + mt[p]][p] = max(dp[t + mt[p]][p], dp[t][p] + 1);
                if(cl[t] > p)dp[t + clt[t]][cl[t]] = max(dp[t + clt[t]][cl[t]], dp[t][p]);
                //printf("%d %d %d
    ", t, p, dp[t][p]);
            }
        }
        for(int p = 1; p <= A; p++)
            ans = max(ans, dp[T][p]);
        printf("%d
    ", ans);    
        
        
    }
    View Code

    第三题

    二分答案。
    枚举距离特殊点最近的建造的树洞是哪一个,记为X。
    在图中删除能够在二分的时间内到达该树洞X的所有点。
    此时图变为若干条独立的链,直接求最少需要的树洞数。
    在所有枚举的情况中取最小值,与K比较确定二分范围变化。

    #include<bits/stdc++.h>
    using namespace std;
    
    const int M = 2005;
    #define ex(i, u) for(int i = h[u]; i; i = G[i].nxt)
    int h[M], dep[M], dis[M][M], n, tot, m, k, root, du[M];
    bool vis[M];
    struct edge{int v,nxt;}G[ M << 2];
    void add(int u, int v){G[++tot].v=v,G[tot].nxt=h[u],h[u]=tot;}
    void bfs(int st){
        queue <int> Q;
        Q.push(st);
        while(!Q.empty()){
            int u = Q.front(); Q.pop();
            ex(i, u){
                int v = G[i].v;
                if(!dis[st][v] && v != st){
                    dis[st][v] = dis[st][u] + 1;
                    Q.push(v);
                }
            }
        }
        
    }
    int tl;
    void dfs(int u){
        tl += (vis[u] = 1);
        ex(i, u){
            int v = G[i].v;
            if(!vis[v])dfs(v);
        }
    }
    
    
    int work(int now, int len){
        memset(vis, 0, sizeof(vis));
        int ans = 0;
        for(int i = 1; i <= n; i++)
            if(dis[now][i] <= len)vis[i] = 1;
        for(int i = 1; i <= n; i++)
            if(!vis[i]){
                dfs(i); int tt = ceil(1.0*tl/(2*len+1));
                ans += tt; tl = 0; 
            }
        return ans;
    }
    
    bool check(int mid){
        int ans = 1e8;
        for(int i = 1; i <= n; i++)
            if(dis[root][i] <= mid)
                ans = min(ans, work(i, mid));
        return ans + 1 <= k;
    }
    
    
    int main(){
        freopen("holes.in","r",stdin);
        freopen("holes.out","w",stdout);
        int ans = 0;
        scanf("%d%d%d", &n, &m, &k);
        int u, v;
        for(int i = 1; i <= m; i++){
            scanf("%d%d", &u, &v);
            add(u, v);du[u]++;
            add(v, u);du[v]++;
        }
        for(int i = 1; i <= n; i++)
            if(du[i] > 2){
                root = i; break;
            }
        if(!root){
            int ans = ceil(1.0*(n - k)/(k << 1));
            printf("%d
    ", ans);
            return 0;
        }
        for(int i = 1; i <= n; i++)bfs(i);
        int lf = 1, rg = n;
        while(lf <= rg){
            int mid = (lf + rg) >> 1;
            if(check(mid))ans = mid, rg = mid - 1;
            else lf = mid + 1;
        }
        printf("%d
    ", ans);
    }
    View Code
  • 相关阅读:
    Spring3.2新注解@ControllerAdvice
    Spring读取加密属性文件处理--待整理
    SpringMVC之三:配置Spring MVC Controller
    深入理解DIP、IoC、DI以及IoC容器
    缓存与数据库一致性之三:缓存穿透、缓存雪崩、key重建方案
    Spring容器初始化过程
    Spring框架中的@Import、@ImportResource注解
    @SpringBootApplication注解分析
    Spring bean加载之1:BeanFactory和FactoryBean
    内存使用情况
  • 原文地址:https://www.cnblogs.com/EdSheeran/p/9507309.html
Copyright © 2020-2023  润新知