• 5.7 ~ 5.12 刷题列表


    USACO Raucous Rockers  搜索水题

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cstdlib>
    using namespace std;
    
    int n, m, t;
    
    int ans;
    
    int a[25];
    
    int rest[25];
    
    int pos;
    
    void dfs(int now, int sum)
    {
        if (now == n + 1){
            ans = max(ans, sum);
            return ;
        }
        
        if (sum + n + 1 - now <= ans) return ;//剪枝
        
        if (rest[pos] >= a[now]){  //xuan ze zhe ge
            rest[pos] -= a[now];
            dfs(now + 1, sum + 1);
            rest[pos] += a[now];
        }
        
        if (pos < m and rest[pos+1] >= a[now])  { // xuan ze xia yi ge
            pos++;
            rest[pos] -= a[now];
            dfs(now + 1, sum + 1);
            rest[pos] += a[now];
            pos--;
        }
        
        dfs(now + 1, sum); //bu xuan ze
        
    }
    
    int main()
    {
        cin >> n >> t >> m;
        for (register int i = 1 ; i <= n ; i ++) scanf("%d", &a[i]);
        
        for (register int i = 1 ; i <= m ; i ++) rest[i] = t;
        
        dfs(1, 0);
        
        cout << ans << endl;
        return 0;
    }
    zZhBr

     Noip2011 聪明的质检员 二分答案,前缀和

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    #define int long long
    
    int n, m, s;
    int w[200010], v[200010];
    int sw[200010], sv[200010];
    
    int li[200010], ri[200010];
    
    int l, r, mid;
    
    int res, sum;
    
    int ans = 0x7f7f7f7f7f7f7f7f7f;
    
    bool check(int x)
    {
        res = 0, sum = 0;
        int aa = 0;
        
        for (int i = 1 ; i <= n ; i ++){
            if(w[i] < x) sv[i] = sv[i-1], sw[i] = sw[i-1];
            else {
                sv[i] = sv[i-1] + v[i];
                sw[i] = sw[i-1] + 1;
            }
        }
        
        for (int i = 1 ; i <= m ; i ++){
            res += (sw[ri[i]] - sw[li[i]-1]) * (sv[ri[i]] - sv[li[i]-1]);
        }
        
    //    printf("mid = %d, res = %d
    ", x, res);
        sum = abs(res - s);
        if(res > s) return 1;
        return 0;
    }
    
    signed main()
    {
        cin >> n >> m >> s;
        
        for (int i = 1 ; i <= n ; i ++){
            scanf("%lld%lld", &w[i], &v[i]);
            sv[i] = sv[i-1] + v[i];
            r = max(r, w[i]);
        }
        
        for (int i = 1 ; i <= m ; i ++){
            scanf("%lld%lld", &li[i], &ri[i]);
        }
        
        while(l <= r){
            mid = l + r >> 1;
            
            bool f = check(mid);
            
            ans = min(ans, sum);
            
            if(f){
                l = mid + 1;
            }
            else r = mid - 1;
        }
        
        cout << ans << endl;
        return 0;
    }
    zZhBr

     HAOI2010音量调节 DP水题(我不会说我因数组开小WA了n次

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    using namespace std;
    
    int n, m, s;
    int a[52];
    bool dp[52][1010];//第i次, 音量为j是否可行 
    
    int main()
    {
        cin >> n >> m >> s;
        
        for (register int i = 1 ; i <= n ; i ++){
            scanf("%d", &a[i]);
        }
        
        dp[0][m] = 1;
        
        for (register int i = 1 ; i <= n ; i ++){
            for (register int j = 0 ; j <= s ; j ++){
                if (dp[i-1][j]){
                    if (j + a[i] <= s) dp[i][j+a[i]] = 1;
                    if (j - a[i] >= 0) dp[i][j-a[i]] = 1;
                }
            }
        }
        
        for (register int i = s ; i >= 0 ; i --){
            if(dp[n][i]) {
                cout << i << endl;
                return 0;
            }
        }
        puts("-1");
        return 0;
        
    }
    zZhBr

     USACO 蹄子剪刀布 DP水题

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define regi register
    
    int n, m;
    
    int a[100010];
    
    int dp[100010][51][4];
    
    inline int win(int x, int y)
    {
        if (x == 1 and y == 2) return 1;
        if (x == 2 and y == 3) return 1;
        if (x == 3 and y == 1) return 1;
        return 0;
    }
    
    inline int Large(int x, int y, int z)
    {
        if (x > y) return x > z ? x : z;
        else return y > z ? y : z;
    }
    
    int ans1, ans2, ans3;
    
    int main()
    {    
        cin >> n >> m;
        
        for (regi int i = 1 ; i <= n ; i++){
            char c;
            cin >> c;
            if (c == 'P') a[i] = 1;
            else if (c == 'H') a[i] = 2;
            else a[i] = 3;
        }
        
        for (regi int i = 1 ; i <= n ; i ++){
            dp[i][0][1] = dp[i-1][0][1] + win(1, a[i]);
            dp[i][0][2] = dp[i-1][0][2] + win(2, a[i]);
            dp[i][0][3] = dp[i-1][0][3] + win(3, a[i]);
        }
        
        for (regi int i = 1 ; i <= n ; i ++){
            for (regi int j = 1 ; j <= m ; j ++){
                dp[i][j][1] = Large(dp[i-1][j][1], dp[i-1][j-1][2], dp[i-1][j-1][3]) + win(1, a[i]);
                dp[i][j][2] = Large(dp[i-1][j][2], dp[i-1][j-1][1], dp[i-1][j-1][3]) + win(2, a[i]);
                dp[i][j][3] = Large(dp[i-1][j][3], dp[i-1][j-1][1], dp[i-1][j-1][2]) + win(3, a[i]);
            }
        }
        
        
        cout << Large(dp[n][m][1], dp[n][m][2], dp[n][m][3]) << endl;;
        return 0;
        
    }
    zZhBr

     USACO 环绕岛屿 直接暴力 挺好的题,我写了题解 ,戳这里

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    using namespace std;
    #define regi register 
    
    int n;
    
    int fa[505];
    
    inline int Find(int x)
    {
        return x == fa[x] ? x : fa[x] = Find(fa[x]);
    }
    
    int dis[505][505];
    
    int cnt;
    
    int ans = 0x7f7f7f7f;
    
    int pos[505];
    
    int main()
    {
        cin >> n;
        
        for (regi int i = 1 ; i <= n ; i ++) fa[i] = i;
        
        memset(dis, 0x7f, sizeof dis);
        
        for (regi int i = 1 ; i <= n ; i ++){
            int x, y;
            scanf("%d%d", &x, &y);
            int fx = Find(x), fy = Find(y);
            if (fx != fy) fa[fx] = fy;
        }
        
        for (regi int i = 1 ; i <= n ; i ++){
            if (fa[i] == i) pos[++cnt] = i;
        }
        
        for (regi int i = 1 ; i <= n ; i ++){
            int fi = Find(i);
            for (regi int j = 1 ; j <= n ; j ++){
                int fj = Find(j);
                int d;
                scanf("%d", &d);
                dis[fi][fj] = min(dis[fi][fj], d);            
            }
        }
        
        for (regi int i = 1 ; i <= cnt ; i ++){
            int sum = 0;
            for (regi int j = 1 ; j <= cnt ; j ++){
                if (i == j) continue;
                sum += dis[pos[i]][pos[j]];
            }
            ans = min(ans, sum);
        }
        
    //    printf("dis==%d
    ", dis[4][10]);
        
        cout << ans * 2 << endl;
        
        return 0;
    }
    zZhBr

     USACO吃巧克力 二分水题, 坑点 : 没吃完的放到最后一天吃,还有记得开long long, 坑了我5次

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    using namespace std;
    #define regi register 
    #define int long long
    
    int n, d;
    
    int a[50005];
    int tim[50005];
    int b[50005];
    
    int l = 1, r, mid;
    
    int ans;
    
    bool check(int x)
    {
        int now = 0, j = 1;
        
        for (regi int i = 1 ; i <= d ; i ++){
            now /= 2;
            while (now < x and j <= n){
                now += a[j];
                b[j] = i;
                j ++;
            }
            if (now < x) return 1;
        }
        
        for (regi int i = 1 ; i <= n ; i ++) tim[i] = d;
        for (regi int i = 1 ; i < j ; i ++) tim[i] = b[i];
        
        return 0;
    }
    
    signed main()
    {
        cin >> n >> d;
        
        for (regi int i = 1 ; i <= n ; i ++){
            scanf("%lld", &a[i]);
            r += a[i];
        }
        
        while (l <= r){
            mid = l + r >> 1;
            bool f = check(mid);
            if (f){
                r = mid - 1;
            }
            else{
                l = mid + 1;
                ans = mid;
            }
        }    
        
        cout << ans << endl;
        
        for (regi int i = 1 ; i <= n ; i ++){
            printf("%lld
    ", tim[i]);
        }
        
        return 0;
    }
    zZhBr
  • 相关阅读:
    2017-2018-1 20155226《信息安全系统设计基础》第5周学习总结
    2017-2018-1 20155226 《信息安全系统设计基础》第四周学习总结
    2017-2018-1 20155226《信息安全系统设计基础》第2周学习总结
    2017-2018-1 20155226 《信息安全系统设计基础》第四周课堂实践
    2017-2018-1 20155226《信息安全系统设计基础》第1周学习总结
    20155226 2016-2017-2 《Java程序设计》课程总结
    20155226 实验五 网络编程与安全
    20155226 实验四 Android开发基础
    2017-2018-20155220 《信息安全系统设计基础》第九周学习总结
    2017-2018-1 20155220 《信息安全系统设计基础》第八周学习总结
  • 原文地址:https://www.cnblogs.com/BriMon/p/9005247.html
Copyright © 2020-2023  润新知