1.贪心算法
每次都选择当前最好的,当前不考虑整体,用局部最优解最后得到整体的最优解。(感觉最简单好理解的一个算法)
2.输入M,N,及N组数据,F[i],J[i];M是你有的资本,获取F[i]就要付出对应的J[i],钱不够可以按比例获取,求能获取到的最大值。
思路:每次用最少的钱获取最大的,即F[i]/J[i]最大,所以讲F[i]/J[i]排序,每次获取最大的,可以按比例,看M能获取到多少。
public class Exercise01 {
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
int m=scan.nextInt();
int n=scan.nextInt();
while(m!=-1&&n!=-1){
List<Jf> list=new ArrayList<Jf>();
double max=0;
for(int i=0;i<n;i++){
int j=scan.nextInt();
int f=scan.nextInt();
Jf jf=new Jf(j,f,(double)j/f);
list.add(jf);
}
Collections.sort(list);
for(int i=0;i<list.size();i++){
if(m>list.get(i).f){
max+=list.get(i).j;
m-=list.get(i).f;
}else{
double t=(double)m/list.get(i).f;
max+=t*list.get(i).j;
break;
}
}
System.out.printf("%.3f",max);
m=scan.nextInt();
n=scan.nextInt();
}
}
}
class Jf implements Comparable<Jf>{
int j;
int f;
double avg;
public Jf(int j,int f,double avg){
this.j=j;
this.f=f;
this.avg=avg;
}
public String toString() {
return "Jf [j=" + j + ", f=" + f + ", avg=" + avg + "]";
}
public int compareTo(Jf o) {
if(this.avg-o.avg > 0.001)
return -1;
else
return 1;
}
}
思路:1.可以根据题意模拟,复杂度有点高。2.可知,每次移动的两房间之间的所有房间号都只能出现一次,出现两次就相交了,所有记录所有经过的房间次数,经过次数最大也就是移动的最小次数。
import java.util.*;
public class Exercise02 {
//一房间往另一房间移桌子,只有一条通道,相交的房间之间不能同时移,不想交的可以同时移,移一次10分钟,求最小时间。
public static void main(String[] args){
Scanner scan=new Scanner(System.in);
int t=scan.nextInt();
while(t--!=0){
int[] cout=new int[401];
int n=scan.nextInt();
while(n--!=0){
int start=scan.nextInt();
int end=scan.nextInt();
int l=Math.min(start, end);
int r=Math.max(start, end);
for(int i=l;i<=r;i++){
cout[i]+=10;
}
}
Arrays.sort(cout);
System.out.println(cout[400]);
}
}
3.
//第一根木棒需要1min的准备时间;在加工了一根长为l,重为w的木棒之后,接着加工一根长为ll(l<=ll),重为ww(w<=ww)的木棒是不需要任何准备时间的。否则需要一分钟的准备时间。给定n根木棒,你要找到最少的准备时间。例如现在有长和重分别为(4,9),(5,2),(2,1),(3,5)和(1,4)的五根木棒,那么所需准备时间最少为2min,顺序为(1,4),(3,5),(4,9),(2,1),(5,2)。
思路:先给数据排序,l大的排前,l相等w大的排前。(因为要利用list遍历时有remove操作,所以要从后往前遍历,从前往后不行,所以小的再最后),利用list每次比较前一个,l和w都比当前的大更改当前l和w为它的l和w并移除它,计数器count+1,循环到list.size=0。
import java.util.*;
public class Exercise03 {
public static void main(String[] args) {
//第一根木棒需要1min的准备时间;
//在加工了一根长为l,重为w的木棒之后,接着加工一根长为ll(l<=ll),重为ww(w<=ww)的木棒是不需要任何准备时间的。否则需要一分钟的准备时间。
//给定n根木棒,你要找到最少的准备时间。例如现在有长和重分别为(4,9),(5,2),(2,1),(3,5)和(1,4)的五根木棒,
//那么所需准备时间最少为2min,顺序为(1,4),(3,5),(4,9),(2,1),(5,2)。
Scanner scan=new Scanner(System.in);
int t=scan.nextInt();
while(t--!=0){
int n=scan.nextInt();
int count=0;
List<Stick> list=new ArrayList<Stick>();
for(int i=0;i<n;i++){
Stick stick=new Stick();
stick.setL(scan.nextInt());
stick.setW(scan.nextInt());
list.add(stick);
}
Collections.sort(list);
while(list.size()!=0){
count+=1;
if(list.size()==1){
break;
}
int l=list.get(list.size()-1).getL();
int w=list.get(list.size()-1).getW();
list.remove(list.size()-1);
for(int i=list.size()-1;i>=0;i--){
if(list.get(i).getL()>=l&&list.get(i).getW()>=w){
l=list.get(i).getL();
w=list.get(i).getW();
list.remove(i);
}
}
}
System.out.println(count);
}
}
}
class Stick implements Comparable<Stick> {
int l;
int w;
public String toString() {
return "Stick [l=" + l + ", w=" + w + "]";
}
public int getL() {
return l;
}
public void setL(int l) {
this.l = l;
}
public int getW() {
return w;
}
public void setW(int w) {
this.w = w;
}
@Override
public int compareTo(Stick o) {
if(this.l!=o.l){
return o.l-this.l;
}else{
return o.w-this.w;
}
}
}