zoukankan      html  css  js  c++  java
  • 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;    
    }
  • 相关阅读:
    记一次 contentInsetAdjustmentBehavior 引发的bug
    Android埋点技术概览
    Android开发快速入门iOS开发概览
    工作项目遇到的一些问题
    ruby操作项目.xcodeproj
    关于performSelector afterDelay:0 的使用
    谷歌Python代码风格指南 中文翻译
    最大子矩阵问题--悬线法dp
    tarjan
    SDU CSPT3模拟
  • 原文地址:https://www.cnblogs.com/Lyush/p/2627241.html
Copyright © 2011-2022 走看看