分组01背包。在一条直线上的点归为一组。
/* 4341 */
#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <climits>
#include <cctype>
#include <cassert>
#include <functional>
#include <iterator>
#include <iomanip>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,1024000") #define sti set<int>
#define stpii set<pair<int, int> >
#define mpii map<int,int>
#define vi vector<int>
#define pii pair<int,int>
#define vpii vector<pair<int,int> >
#define rep(i, a, n) for (int i=a;i<n;++i)
#define per(i, a, n) for (int i=n-1;i>=a;--i)
#define clr clear
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1 typedef struct mine_t {
int x, y, t, v; friend bool operator< (const mine_t& a, const mine_t& b) {
int tmp = a.x * b.y - a.y * b.x;
if (tmp != )
return tmp < ;
return a.y < b.y;
}
} mine_t; const int maxn = ;
const int maxt = ;
mine_t mine[maxn];
int dp[maxt];
int B[maxn][maxn];
int sz[maxn];
int n, T; bool cmp(int i) {
return i+<n && mine[i].x*mine[i+].y==mine[i].y*mine[i+].x;
} void solve() {
int bn = ; sort(mine, mine+n);
memset(sz, , sizeof(sz));
rep(i, , n) {
B[bn][sz[bn]++] = i;
if (cmp(i)) {
mine[i+].t += mine[i].t;
mine[i+].v += mine[i].v;
} else {
++bn;
}
} memset(dp, , sizeof(dp));
rep(i, , bn) {
per(j, , T+) {
rep(k, , sz[i]) {
int id = B[i][k];
int t = mine[id].t;
int v = mine[id].v;
if (j >= t)
dp[j] = max(dp[j], dp[j-t]+v);
}
}
} int ans = dp[T];
printf("%d\n", ans);
} int main() {
ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif int t = ; while (scanf("%d %d", &n, &T) != EOF) {
rep(i, , n)
scanf("%d %d %d %d", &mine[i].x, &mine[i].y, &mine[i].t, &mine[i].v);
printf("Case %d: ", ++t);
solve();
} #ifndef ONLINE_JUDGE
printf("time = %d.\n", (int)clock());
#endif return ;
}
数据发生器。
from copy import deepcopy
from random import randint, shuffle
import shutil
import string def GenDataIn():
with open("data.in", "w") as fout:
t = 20
bound = 10**5
ld = list(string.digits)
# fout.write("%d\n" % (t))
for tt in xrange(t):
n = randint(1, 200)
T = randint(1, 200**2)
fout.write("%d %d\n" % (n, T))
for i in xrange(n):
x = randint(-200, 200)
y = randint(0, 200)
t = randint(1, 200)
v = randint(0, 200)
fout.write("%d %d %d %d\n" % (x, y, t, v)) def MovDataIn():
desFileName = "F:\eclipse_prj\workspace\hdoj\data.in"
shutil.copyfile("data.in", desFileName) if __name__ == "__main__":
GenDataIn()
MovDataIn()