• ZOJ 3769 Diablo III(分组背包)


    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3769

    题意:
    有13种装备,每种装备值可以穿戴一种,特殊的就是双手武器和单手武器,双手武器和单手武器+盾只能选择一种,戒指可以双手各戴一个。每个装备都有一个攻击值和防御值,现在要在防御值至少到达m的情况下可以达到的最大攻击力。

    思路:
    分组背包题目。

    把单手武器和盾组合起来放到双手武器当中,戒指也需要两两组合。

    接下来就是一个分组背包了,比较重要的是这道题目需要开二维数组,因为题目要求的是至少要达到m的容量,如果超过了m容量,就需要按m来算。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<sstream>
     6 #include<vector>
     7 #include<stack>
     8 #include<queue>
     9 #include<cmath>
    10 #include<map>
    11 #include<set>
    12 using namespace std;
    13 typedef long long ll;
    14 typedef pair<int,int> pll;
    15 const int INF = 0x3f3f3f3f;
    16 const int maxn = 400 + 5;
    17 
    18 int n,m;
    19 int d[15][50005];
    20 vector<pll> v[15];
    21 map<string,int> ID;
    22 
    23 void init()
    24 {
    25     ID["Head"] = 1;      ID["Shoulder"] = 2;  ID["Neck"] = 3;
    26     ID["Torso"] = 4;     ID["Hand"] = 5;      ID["Wrist"] = 6;
    27     ID["Waist"] = 7;     ID["Legs"] = 8;      ID["Feet"] = 9;
    28     ID["Finger"] = 10;   ID["Shield"] = 11;   ID["Weapon"] = 12;
    29     ID["Two-Handed"] = 13;
    30 }
    31 
    32 bool cmp(const vector<pll> a, const vector<pll> b)
    33 {
    34     return a.size()>b.size();
    35 }
    36 
    37 int main()
    38 {
    39     //freopen("in.txt","r",stdin);
    40     init();
    41     int T;
    42     scanf("%d",&T);
    43     while(T--)
    44     {
    45         for(int i=1;i<13;i++)  v[i].clear();
    46 
    47         scanf("%d%d",&n,&m);
    48         for(int i=0;i<n;i++)
    49         {
    50             int D,T; string s;
    51             cin>>s>>D>>T;
    52             v[ID[s]].push_back(make_pair(D,T));
    53             if(ID[s]==11 || ID[s]==12)  v[13].push_back(make_pair(D,T));
    54         }
    55 
    56         //合并单手武器和盾牌
    57         for(int i=0;i<v[11].size();i++)
    58         {
    59             for(int j=0;j<v[12].size();j++)
    60             {
    61                 v[13].push_back(make_pair(v[11][i].first+v[12][j].first,v[11][i].second+v[12][j].second));
    62             }
    63         }
    64 
    65         v[11].clear();
    66         v[12].clear();
    67         
    68         //合并戒指并且储存在v[10]中
    69         int len=v[10].size();
    70         for(int i=0;i<len;i++)
    71         {
    72             for(int j=i+1;j<len;j++)
    73             {
    74                 v[10].push_back(make_pair(v[10][i].first+v[10][j].first,v[10][i].second+v[10][j].second));
    75             }
    76         }
    77 
    78         memset(d,-1,sizeof(d));
    79         sort(v+1,v+14,cmp);
    80 
    81         d[0][0]=0;
    82         for(int i=1;i<=11;i++)
    83         {
    84             for(int j=0;j<=m;j++)
    85             {
    86                 d[i][j]=max(d[i][j],d[i-1][j]);  //第i组的状态有第i-1组状态而来
    87                 if(d[i-1][j]==-1)  continue;
    88                 for(int k=0;k<v[i].size();k++)
    89                 {
    90                     int tmp=min(v[i][k].second+j,m);  //如果容量超过了m,那么就按m来算
    91                     d[i][tmp]=max(d[i][tmp],d[i-1][j]+v[i][k].first);  //由第i-1组更新
    92                 }
    93             }
    94         }
    95         printf("%d
    ",d[11][m]);
    96     }
    97     return 0;
    98 }
  • 相关阅读:
    MyBatis入门
    Java JDBC
    Spring MVC
    Java内存模型
    Java日志
    Java I/O模型
    Java异常处理
    Java泛型设计
    Java反射
    Java代理
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7232096.html
Copyright © 2020-2023  润新知