HDU 4341 Gold miner (分组背包问题)
2013-04-10 21:01
405 查看
Gold miner
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1124 Accepted Submission(s): 458
Problem Description Homelesser likes playing Gold miners in class. He has to pay much attention to the teacher to avoid being noticed. So he always lose the game. After losing many times, he wants your help.
To make it easy, the gold becomes a point (with the area of 0). You are given each gold's position, the time spent to get this gold, and the value of this gold. Maybe some pieces of gold are co-line, you can only get these pieces in order. You can assume it can turn to any direction immediately. Please help Homelesser get the maximum value.
Input
There are multiple cases. In each case, the first line contains two integers N (the number of pieces of gold), T (the total time). (0<N≤200, 0≤T≤40000) In each of the next N lines, there four integers x, y (the position of the gold), t (the time to get this gold), v (the value of this gold). (0≤|x|≤200, 0<y≤200,0<t≤200, 0≤v≤200)
Output
Print the case number and the maximum value for each test case.
Sample Input
3 10
1 1 1 1
2 2 2 2
1 3 15 9
3 10
1 1 13 1
2 2 2 2
1 3 4 7
Sample Output
Case 1: 3
Case 2: 7
思路:题目由于对于共线的点,必须按顺序去拿,可以按点的x做升序排序,然后把斜率相同的点分到同一个组。对于同组的点,第一个点的价值为v1,时间为t1,第二个点的价值为v1+v2,时间为t1+t2,接下来是v1+v2+v3,t1+t2+t3...以此类推,这样就能保证同组里的每一个物品是互斥的,并且是按顺序去拿的。分组分好以后,就是直接按分组背包的做法做了。
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
View Code
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1124 Accepted Submission(s): 458
Problem Description Homelesser likes playing Gold miners in class. He has to pay much attention to the teacher to avoid being noticed. So he always lose the game. After losing many times, he wants your help.
To make it easy, the gold becomes a point (with the area of 0). You are given each gold's position, the time spent to get this gold, and the value of this gold. Maybe some pieces of gold are co-line, you can only get these pieces in order. You can assume it can turn to any direction immediately. Please help Homelesser get the maximum value.
Input
There are multiple cases. In each case, the first line contains two integers N (the number of pieces of gold), T (the total time). (0<N≤200, 0≤T≤40000) In each of the next N lines, there four integers x, y (the position of the gold), t (the time to get this gold), v (the value of this gold). (0≤|x|≤200, 0<y≤200,0<t≤200, 0≤v≤200)
Output
Print the case number and the maximum value for each test case.
Sample Input
3 10
1 1 1 1
2 2 2 2
1 3 15 9
3 10
1 1 13 1
2 2 2 2
1 3 4 7
Sample Output
Case 1: 3
Case 2: 7
思路:题目由于对于共线的点,必须按顺序去拿,可以按点的x做升序排序,然后把斜率相同的点分到同一个组。对于同组的点,第一个点的价值为v1,时间为t1,第二个点的价值为v1+v2,时间为t1+t2,接下来是v1+v2+v3,t1+t2+t3...以此类推,这样就能保证同组里的每一个物品是互斥的,并且是按顺序去拿的。分组分好以后,就是直接按分组背包的做法做了。
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
View Code
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #define MAX 40005 7 #define SIZE 205 8 9 using namespace std; 10 11 struct Gold 12 { 13 int x,y,t,v; 14 }; 15 16 int line[SIZE][SIZE],num[SIZE]; //line存储分组情况,其中line[1][1]代表的是第一组第一个物品,num存的是该组里物品的件数 17 bool used[SIZE]; //判断该物品是否已经被纳入一个物品组中 18 Gold gold[SIZE]; 19 int dp[MAX]; 20 int N,T; 21 22 bool cmp(Gold a,Gold b) //升序 23 { 24 return abs(a.x) < abs(b.x); 25 } 26 27 void init() 28 { 29 memset(dp,0,sizeof(dp)); 30 memset(line,0,sizeof(line)); 31 memset(num,0,sizeof(num)); 32 memset(used,0,sizeof(used)); 33 } 34 35 int main() 36 { 37 int Case = 1; 38 while(~scanf("%d%d",&N,&T)) 39 { 40 for(int i=1; i<=N; i++) 41 scanf("%d %d %d %d",&gold[i].x, &gold[i].y, &gold[i].t, &gold[i].v); 42 sort(gold+1, gold+1+N, cmp); 43 init(); 44 int index = 1; 45 for(int i=1; i<=N; i++) //分组 46 { 47 if(used[i])continue; 48 used[i] = true; 49 line[index][++num[index]] = i; //存储该组的第一件物品 50 for(int j=i+1; j<=N; j++) 51 { 52 if(!used[j] && gold[i].x*gold[j].y == gold[i].y*gold[j].x) 53 { 54 line[index][++num[index]] = j; //把斜率相同的放到同个组 55 used[j] = true; 56 } 57 } 58 index ++; 59 } 60 index --; 61 for(int i=1; i<=index; i++) //更新组成员的价值和时间 62 { 63 for(int j=2; j<=num[i]; j++) 64 { 65 gold[line[i][j]].t += gold[line[i][j-1]].t; 66 gold[line[i][j]].v += gold[line[i][j-1]].v; 67 } 68 } 69 for(int i=1; i<=index; i++) //分组背包 70 { 71 for(int j=T; j>=0; j--) 72 { 73 for(int k=1; k<=num[i]; k++) 74 if(j-gold[line[i][k]].t>=0) 75 dp[j] = max(dp[j],dp[j-gold[line[i][k]].t]+gold[line[i][k]].v); 76 } 77 } 78 printf("Case %d: %d\n",Case++,dp[T]); 79 } 80 return 0; 81 }
相关文章推荐
- HDU 4341 Gold miner(分组的背包问题)
- hdu - 4341 - Gold miner - 分组背包
- hdu 4341 Gold miner 分组背包
- HDU 4341 Gold miner (分组背包)
- HDU 4341 Gold miner 分组背包变形
- HDU 4341 Gold miner 【思维 + 分组背包好题】
- 【HDU - 4341】Gold miner(分组背包)
- hdu 4341 Gold miner(分组背包)
- hdu 4341 Gold miner (分组背包)
- HDU-4341 Gold miner 分组背包
- HDU 4341 Gold miner (分组背包)
- HDU 4341 Gold miner(分组背包)
- hdu 4341 Gold miner 需要处理的分组背包 蛮有意义的题目
- HDU4341——Gold miner(分组背包)
- HDU 4341 Gold miner(DP 分组背包)
- HDU 4341 Gold miner (分组背包)
- hdu 4341 Gold miner 分组背包
- HDU 4341 Gold miner (分组背包)
- hdu 4341 Gold miner(分组01背包)
- hdu 4341(分组背包(好题))