SRM308 D2H TreasuresPacking

TopCoder Statistics - Problem Statement

This problem statement is the exclusive and proprietary property of TopCoder, Inc. Any unauthorized use or reproduction of this information without the prior written consent of TopCoder, Inc. is strictly prohibited. (c)2010, TopCoder, Inc. All rights reserved.

$weight, cost,$分割できるかどうかが与えられる.$W$まで持つことが出来る時の$cost$の最大値を求める.
まず分割できないものを先に$dp[i][j] := i$番目まで見た時, 重さ$j$の時の最大値として動的計画法.分割出来るものは全て重さ$1$ずつに分けて,価値が高い順に使うのが良い.$dp[i][j] + (W - j)$個の分割したものを出してその最大値を取った.

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include <iostream>
#include <sstream>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <map>
#include <set>
#include <queue>

#define REP(i,k,n) for(int i=k;i<n;i++)
#define rep(i,n) for(int i=0;i<n;i++)
#define each(it,v) for(__typeof((v).begin()) it=(v).begin();it!=(v).end();it++)
#define INF 1<<30
#define mp make_pair

using namespace std;
typedef long long ll;
typedef pair<int, int> P;

vector<string> split(const string &str, char delim) {
  vector<string> res;
  size_t current = 0, found;
  while((found = str.find_first_of(delim, current)) != string::npos) {
      res.push_back(string(str, current, found - current));
      current = found + 1;
  }
  res.push_back(string(str, current, str.size() - current));
  return res;
}

double dp[55][10005];

class TreasuresPacking {
  public:
  double maximizeCost(vector <string> treasures, int W) {
      vector<int> w, c;
      vector<double> v;

      rep(i, treasures.size()) {
          int a, b;
          vector<string> ret = split(treasures[i], ' ');

          {
              stringstream ss(ret[0]);
              ss >> a;
          }
          {
              stringstream ss(ret[1]);
              ss >> b;
          }

          if(ret[2] == "Y") {
              REP(i, 1, a + 1) {
                  v.push_back(1.0 / a * b);
              }
          } else {
              w.push_back(a);
              c.push_back(b);
          }
      }

      sort(v.begin(), v.end(), greater<double>());
      v.insert(v.begin(), 0);
      REP(i, 1, v.size()) {
          v[i] += v[i-1];
      }

      int n = w.size();
      memset(dp, 0, sizeof(dp));

      rep(i, n) {
          rep(j, W + 1) {
              if(j - w[i] < 0) {
                  dp[i+1][j] = dp[i][j];
              } else {
                  dp[i+1][j] = max(dp[i][j], dp[i][j-w[i]] + c[i]);
              }
          }
      }

      double ans = 0;
      rep(j, W + 1) {
          int m = W - j;
          if(m < v.size()) {
              ans = max(ans, dp[n][j] + v[m]);
          }
      }

      return ans;
  }
};
Aug 31st, 2016