HDU 4341 Gold miner 分组背包

第一篇题解- -。

 

传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4341

题意:给出黄金矿工的地图上各个金块的坐标,得到它的时间,价值,

在一条线上的只能先抓第一个才能抓第二个,求限定时间内,最多能获得

多少钱。

初始点是(0,0)

 

把在一条直线的分为一个组,然后组的成员就是 第一个,第一个+第二个.....;

每组取一个或者不取,这样就是分组背包问题;

注意对金块按y排序,这样就能保证第一个在第二个前...;

确认在一条线上用 x/y 值来存WA了,要用交叉相乘且相等确认。

 

————————————————————————————————————

渣渣之见,随便转载。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define maxn 205
 5 #define maxx 40010
 6 using namespace std;
 7 
 8 int dp[maxx],tm[maxn],gr[maxn];
 9 
10 typedef struct{
11     int x,y;
12     int t,v;
13 }hehe;
14 
15 bool cmp(hehe a,hehe b)
16 {
17     return a.y<b.y;      // 对y进行排序
18 }
19 
20 typedef struct{
21     int t,v;
22 }he;
23 
24 he b[maxn][maxn];
25 hehe a[maxn];
26 
27 int is_oneline(int i,int j)         // 一开始在结构体中用 x/y 存了比较WA了
28 {                        // 所以这里用向量乘积交叉相乘且相等
29     if(a[i].x*a[j].y==a[i].y*a[j].x) 
30         return 1;
31     return 0;
32 }
33 
34 int main()
35 {
36 //    freopen("C:\\Users\\ZDH\\Desktop\\a.txt","r",stdin);
37     int n,T,ca=1;
38     while(~scanf("%d %d",&n,&T))
39     {
40         memset(dp,0,sizeof dp);
41         memset(tm,0,sizeof tm);
42         memset(gr,0,sizeof gr);
43         
44         int gro=0;
45         for(int i=0;i<n;i++)
46             scanf("%d %d %d %d",&a[i].x,
47                    &a[i].y,&a[i].t,&a[i].v);
48         sort(a,a+n,cmp);
49         
50         for(int i=0;i<n;i++)
51             if(tm[i]==0)
52             {
53                 tm[i]=1;
54                 b[gro][gr[gro]].t=a[i].t;
55                 b[gro][gr[gro]].v=a[i].v;
56                 gr[gro]++;
57                 for(int j=0;j<n;j++)
58                     if(tm[j]==0 && is_oneline(i,j) )
59                     {
60                         tm[j]=1;
61                         b[gro][gr[gro]].t=b[gro][gr[gro]-1].t+a[j].t;
62                         b[gro][gr[gro]].v=b[gro][gr[gro]-1].v+a[j].v;
63                         gr[gro]++;
64                     }
65                 gro++;
66             }
67             
68         for(int i=0;i<gro;i++)
69             for(int t=T;t>=0;t--)
70                 for(int j=0;j<gr[i];j++)
71                     if(t>=b[i][j].t)                // 分组背包的DP dp[v]=max(dp[v],dp[v-vi[i]]+w[i]);
72                         dp[t]=max(dp[t],dp[t-b[i][j].t]+b[i][j].v);        
73                         
74         printf("Case %d: %d\n",ca++,dp[T]);
75     }
76 }

 

posted @ 2016-03-15 20:40  后知后觉丶  阅读(171)  评论(1编辑  收藏  举报