1. 程式人生 > 其它 >DP 做題記錄

DP 做題記錄

UVA

#include <stdio.h>
#include <string.h>
#include <iostream>

#define cin std::cin
#define cout std::cout
#define endl std::endl

const int N = 210;
const int M = 21;

int T, n, m, dp[M][M*M*2];
int from[N][M][M*M*2];
int a[N], b[N], choose[M];
int anscnt, D, P;

bool check(int x) { return x<0 || x>800; }
int f(int x, int tag) { return tag * x + 400; }

void getans(int I, int J, int K) {
  if (!J) return ;
  // which didn't choose anyone
  int From = from[I][J][K];
  // next I is the From
  getans(From-1, J-1, K-a[From]+b[From]);
  choose[++anscnt] = From;
  D += a[From], P += b[From];
  return ;
}

int main() {
  while (cin >> n >> m) {
    ++T, anscnt = 0, D = P = 0; // testcase
    if (!n && !m) return 0;
    for (int i=1; i<=n; ++i)
      cin >> a[i] >> b[i];
    memset(dp, 0xcf, sizeof dp);
    // get the maximum, so set the minimum
    dp[0][400] = 0;
    // set 0 -> 400, as the first-val
    memset(from, 0, sizeof from);
    for (int i=1; i<=n; ++i) {
      for (int j=0; j<=m; ++j)
        for (int k=0; k<=800; ++k)
          from[i][j][k] = from[i-1][j][k];
      for (int j=m; j >= 1; --j)
        for (int k=0; k<=800; ++k) {
          int cur = k - a[i] + b[i];
          // which position the value comes from
          if (check(cur)) continue;
          // just choose this position
          if (dp[j][k] < dp[j-1][cur] + a[i] + b[i]) {
            dp[j][k] = dp[j-1][cur] + a[i] + b[i];
            from[i][j][k] = i;
          }
        }
    }
    int pos = 0;
    for (int i=0; i<=400; ++i) {
      if (dp[m][f(i,1)] >= 0 &&
      dp[m][f(i,1)] >= dp[m][f(i,-1)]) {
        pos = f(i,1); break;
      } else if (dp[m][f(i,-1)] >= 0) {
        pos = f(i,-1); break;
      }
    }
    getans(n, m, pos);
    // through the paths, to get the answers
    cout << "Jury #" << T << endl;
    cout << "Best jury has value " << D;
    cout << " for prosecution and value " << P;
    cout << " for defence:" << endl;
    for (int i=1; i<=anscnt; ++i)
      cout << ' ' << choose[i];
    puts(""), puts("");
  }
}