zoukankan      html  css  js  c++  java
  • [kuangbin带你飞]专题十二 基础DP1 题解+总结

    kuangbin带你飞:点击进入新世界

    文章目录

    1.Max Sum Plus Plus

    原题链接:传送门

    2.Ignatius and the Princess IV

    原题链接:传送门

    思路:hash存储(感觉和dp没啥关系啊。。)

    #include<bits/stdc++.h>
    using namespace std;
    map<int, int>mp; int n, t;
    int main() {
        freopen("in.txt", "r", stdin);
        ios::sync_with_stdio(false); cin.tie(0);
        while (cin >> n) {
            mp.clear();
            for (int i = 0; i < n; ++i) { cin >> t; mp[t]++; }
            for (auto &p : mp) {
                if (p.second >= (n + 1) / 2) { cout << p.first << endl; break; }
            }
        }
    }
    

    3.Monkey and Banana

    原题链接:传送门

    解析:对于所给的砖块可以有6种组合(即:长宽高打乱)所以最终的 $ index = 6 * n$

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1000;
    struct node {
        int l, r, w;//长宽高
    }a[maxn];
    
    int n, r, w, l;
    
    bool cmp(node &a, node &b) {
        if (a.l == b.l)return a.r < b.r;
        return a.l < b.l;
    }
    
    int dp[maxn];
    
    int main() {
        freopen("in.txt", "r", stdin);
        ios::sync_with_stdio(false); cin.tie(0);
        int Case = 1;
        while (cin >> n && n) {
            int index = 1;
            for (int i = 0; i < n; ++i) {
                cin >> l >> r >> w;
                a[index].l = l, a[index].r = r, a[index++].w = w;
                a[index].l = r, a[index].r = l, a[index++].w = w;
                a[index].l = w, a[index].r = r, a[index++].w = l;
                a[index].l = l, a[index].r = w, a[index++].w = r;
                a[index].l = r, a[index].r = w, a[index++].w = l;
                a[index].l = w, a[index].r = l, a[index++].w = r;
            }
            sort(a + 1, a + index + 1,cmp);//根据长宽排序
            memset(dp, 0,sizeof dp);
            int ans = 0;
            for(int i = 1;i <= index;++i)
                for (int j = 1; j <= index; ++j) {
                    if (a[i].r < a[j].r && a[i].l < a[j].l)
                        dp[j] = max(dp[j], dp[i] + a[j].w), ans = max(ans, dp[j]);
                }
            cout << "Case " << Case++ << ": maximum height = " << ans << endl;
        }
    }
    

    4.Doing Homework

    HDU - 1074

    解析:

    先大致说说状态压缩,假设有三门作业a,b,c
    那么,abc都做完即111,111可由101,110,011任意一个来得到。而101可以从100或者001来得到,这就是状态压缩dp的一个基本的状态转移。

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 16;
    struct Node
    {
        char str[109];
        int want, need;
    }node[N];
    
    struct DP
    {
        int now, sum, next, pos;
    }dp[1 << N];
    
    void put_ans(int x)
    {
        if (dp[x].next != -1)
        {
            put_ans(dp[x].next);
            printf("%s
    ", node[dp[x].pos].str);
        }
    }
    
    int main()
    {
        freopen("in.txt", "r", stdin);
        int T;
        scanf("%d", &T);
        while (T--)
        {
            int n;
            scanf("%d", &n);
            for (int i = 0; i < n; i++)
                scanf("%s%d%d", node[i].str, &node[i].want, &node[i].need);
            dp[0].now = dp[0].sum = 0;
            dp[0].next = dp[0].pos = -1;
            int m = (1 << n) - 1;
            for (int i = 1; i <= m; i++)
            {
                dp[i].sum = 0x3f3f3f3f;
                for (int j = 0; j < n; j++)
                {
                    if ((1 << j) & i)
                    {
                        int k = i - (1 << j);
                        int v = dp[k].now + node[j].need - node[j].want;
                        v = max(v, 0);
                        if (dp[i].sum >= dp[k].sum + v)
                        {
                            dp[i].sum = dp[k].sum + v;
                            dp[i].now = dp[k].now + node[j].need;
                            dp[i].next = k;
                            dp[i].pos = j;
                        }
                    }
                }
            }
            printf("%d
    ", dp[m].sum);
            put_ans(m);
        }
        return 0;
    }
    

    5.Super Jumping! Jumping! Jumping!

    HDU - 1087

    解析:注意题目是严格上升子序列并不是连续上升子序列(导致我写错了转移方程2333)

    #include<bits/stdc++.h>
    using namespace std;
    
    #define ms(a,b) (a,b,sizeof a)
    
    const int maxn = 1e3 + 10;
    int dp[maxn], a[maxn];
    int n;
    
    int main() {
        freopen("in.txt", "r", stdin);
        ios::sync_with_stdio(false); cin.tie(0);
        while (cin >> n && n) {
            ms(dp, 0);
            for (int i = 0; i < n; ++i)
                cin >> a[i], dp[i] = a[i];
    
            int ans = 0;
    
            for (int i = 0; i < n; ++i)
            {
                for (int j = i + 1; j < n; ++j)
                {
                	if (a[j] > a[i])
                        dp[j] = max(dp[j], dp[i] + a[j]);
                }
                ans = max(ans, dp[i]);
            }
            cout << ans << endl;
        }
    }
    

    同样是LIS模板题:最少拦截系统:传送门

    Piggy-Bank

    HDU - 1114

    
    
  • 相关阅读:
    自定义文书思路
    传输
    Netty的组件和设计
    第一款Netty应用程序
    Netty异步和事件驱动
    初识MQTT
    TCP/IP协议分层模型
    uni原生插件的开发(安卓)
    uniapp离线打包记录
    日常问题处理:Linux通过设备名称如何查看硬盘SN
  • 原文地址:https://www.cnblogs.com/RioTian/p/13325440.html
Copyright © 2011-2022 走看看