Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1488 Accepted Submission(s): 592
题意来自:http://www.cnblogs.com/kuangbin/archive/2012/08/09/2629579.html
import java.io.*; import java.util.*; public class Main{ int N,T,x,y,t,v,size=205,MAX=40005; int[] number; boolean[] boo; Node[] node; int[] dp; int[][] group; public static void main(String args[]){ new Main().work(); } void work(){ Scanner sc=new Scanner(new BufferedInputStream(System.in)); int Case=1; while(sc.hasNext()){ N=sc.nextInt(); T=sc.nextInt(); node=new Node[N]; boo=new boolean[size]; dp=new int[MAX]; group=new int[size][size]; number=new int[size]; for(int i=0;i<N;i++){ x=sc.nextInt(); y=sc.nextInt(); t=sc.nextInt(); v=sc.nextInt(); node[i]=new Node(x,y,t,v); } Arrays.sort(node); int index=0; // 背包分组 for(int i=0;i<N;i++){ if(boo[i]) continue; boo[i]=true; group[index][number[index]++]=i; for(int j=i+1;j<N;j++){ if(!boo[j]&&node[i].x*node[j].y==node[i].y*node[j].x){ boo[j]=true; group[index][number[index]++]=j; } } index++; } //更新每个分组的信息 for(int i=0;i<index;i++){ for(int j=1;j<number[i];j++){ node[group[i][j]].t+=node[group[i][j-1]].t; node[group[i][j]].v+=node[group[i][j-1]].v; } } //分组背包 for(int i=0;i<index;i++){ for(int j=T;j>=0;j--){ for(int k=0;k<number[i];k++){ int u=group[i][k]; if(j>=node[u].t){ dp[j]=Math.max(dp[j],dp[j-node[u].t]+node[u].v); } } } } System.out.println("Case "+Case+++": "+dp[T]); } } class Node implements Comparable<Node>{ int x; int y; int t; int v; Node(int x,int y,int t,int v){ this.x=x; this.y=y; this.t=t; this.v=v; } public int compareTo(Node o) { if(this.x*o.y>this.y*o.x)//如果斜率不相等,按斜率大小从小到大进行排序 return 1; else if(this.x*o.y==this.y*o.x&&this.y>o.y)//如果斜率相等,按它到y轴的距离从小到大进行排序 return 1; return -1; } } }