• HDU4341 Gold miner 分组背包


    这里有多个点与原点的连线共线的话,那么需要对其进行并组,将前一个作为单独的一个,把前两个作为单独的一个...最后直接分组背包就可以了。

    代码如下:

    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define MAXN 205
    using namespace std;
    
    int N, M, cnt[MAXN], vis[MAXN], idx;
    
    int f[40005];
    
    struct Node
    {
        int x, y, t, v;
        bool operator < (Node temp) const
        {
            return y < temp.y;
        } // 对y轴进行排序,这样保证能够先得到最近的点 
    }e[MAXN];
    
    struct Team
    {
        int t, v;
    }p[MAXN][MAXN];
    
    bool Inline(int a, int b)
    {
        return e[a].x * e[b].y == e[a].y * e[b].x;
    }
    
    void init()
    {
        int st = 0, sv = 0;
        idx = 0;
        memset(vis, 0, sizeof (vis));
        memset(cnt, 0, sizeof (cnt));
        for (int i = 1; i <= N; ++i) {
            if (!vis[i]) {
                vis[i] = 1;
                ++idx, ++cnt[idx];
                st = e[i].t, sv = e[i].v;
                p[idx][cnt[idx]].t = st;
                p[idx][cnt[idx]].v = sv;
                for (int j = 1; j <= N; ++j) {
                    if (!vis[j] && Inline(i, j)) {
                        vis[j] = 1; 
                        ++cnt[idx];
                        st += e[j].t, sv += e[j].v;
                        p[idx][cnt[idx]].t = st;
                        p[idx][cnt[idx]].v = sv;
                    }
                }
            }
        }
    }
    
    void solve()
    {
        memset(f, 0, sizeof (f));
        for (int i = 1; i <= idx; ++i) { // 首先考虑到某一组,得到这一组的最佳答案
            for (int t = M; t >= 0; --t) { // 由于一组中只能够取一件物品,所以这个循环在外层 
                for (int j = 1; j <= cnt[i]; ++j) {
                    if (t >= p[i][j].t) {
                        f[t] = max(f[t], f[t-p[i][j].t] + p[i][j].v);
                    }
                }
            }
        }
        printf("%d\n", f[M]);
    }
    
    int main()
    {
        int ca = 0;
        while (scanf("%d %d", &N, &M) == 2) {
            for (int i = 1; i <= N; ++i) {
                scanf("%d %d %d %d", &e[i].x, &e[i].y, &e[i].t, &e[i].v);
            }
            sort(e+1, e+1+N);
            printf("Case %d: ", ++ca);
            init();
            solve();
        }
        return 0;    
    }
  • 相关阅读:
    二维码物流方面的应用与用户体验方面的改进
    css3文本字体
    css文本样式及控制文本的大小写
    css基础知识之列表
    css基础知识之属性选择器
    css基础内容之background
    webstorm常用快捷键
    canvas标签的使用
    HTML格式化
    a标签链接到当前页内指定位置
  • 原文地址:https://www.cnblogs.com/Lyush/p/2627241.html
Copyright © 2020-2023  润新知