题意:
挖金矿,人在(0,0)点
n个金子 游戏时间为T
下面n行
(x, y) cost val
且若人 和 多块金子共线时,只能先取最近的金子,依次取,就是和游戏一样的。
且所有点只在1 2象限
思路:
我们先把所有共线的点分组
对于每组的物品,我们都可以认为取这个物品的花费就是前面所有物品的花费总和,而价值就是前面所有物品的价值总和。
这样就能消除每组物品的先取后取的影响了,但有一个情况就是这组至多只能取一个物品,所以每个状态只能是取了这个物品后或者是原始状态。
用原始状态转移,然后和原始状态取个最大值。
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstdio>
#include <map>
#include <vector>
typedef long long ll;
template <class T>
inline bool rd(T &ret) {
char c; int sgn;
if(c=getchar(),c==EOF) return 0;
while(c!='-'&&(c<'0'||c>'9')) c=getchar();
sgn=(c=='-')?-1:1;
ret=(c=='-')?0:(c-'0');
while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
ret*=sgn;
return 1;
}
template <class T>
inline void pt(T x) {
if (x <0) {
putchar('-');
x = -x;
}
if(x>9) pt(x/10);
putchar(x%10+'0');
}
const int N = 50000;
using namespace std;
typedef pair<int,int> pii;
int t;
void solve(int T, int V, int *d){
for(int j = t; j >= T; j --) {
if(d[j] <= d[j-T] + V)
d[j] = d[j-T] + V;
}
}
int n, tim[250], val[250], x[250], y[250], d2[N], st[N];
bool cmp(int a, int b){
return x[a]*x[a]+y[a]*y[a] < x[b]*x[b]+y[b]*y[b];
}
bool Coline(int a, int b){
return x[a]*y[b] == x[b]*y[a];
}
vector<int>G[205];
int d[N], top;
void input(){
for(int i = 1; i <= n; i++) {
rd(x[i]); rd(y[i]); rd(tim[i]); rd(val[i]);
}
top = 0;
for(int i = 1; i <= n; i++)
{
bool yes = false;
for(int j = 0; j < top && false == yes; j++)
if(Coline(i, G[j][0]))
{
G[j].push_back(i);
yes = true;
}
if(yes)continue;
G[top].clear(); G[top++].push_back(i);
}
}
int main(){
int Cas = 1;;
while(cin>>n>>t){
input();
memset(d, 0, sizeof d);
for(int i = 0; i < top; i++)
{
sort(G[i].begin(), G[i].end(), cmp);
memcpy(d2, d, sizeof d);
memcpy(st, d, sizeof d);
int V = 0, T = 0;
for(int j = 0; j < G[i].size(); j++)
{
solve(T + tim[G[i][j]], V + val[G[i][j]], st);
T += tim[G[i][j]];
V += val[G[i][j]];
for(int k = 0; k <= t; k++)
d[k] = max(d[k], st[k]);
if(T > t) break;
memcpy(st, d2, sizeof d);
}
}
printf("Case %d: %d\n", Cas++, d[t]);
}
return 0;
}
/*
2 2
1 1 1 1
2 2 1 2
3 5
1 1 4 1
2 2 2 100
1 3 4 7
3 8
-1 1 4 2
1 1 5 1
2 2 2 100
3 8
1 1 5 1
2 2 2 100
-1 1 4 2
*/