贪心算法的两个简单解决问题

1.【活动安排问题】设有n个活动的集合E={1,2,...n},其中每个活动都要求使用同一资源,如演讲会场等,而在同一时间内只有一个活动能使用这一资源。每个活动i都有一个要求使用该资源的起始时间si和fi,且si<fi。如果选择了活动i,则它在半开时间区间[si,fi)内占用资源。若区间[si,fi)和[sj,fj)不相交,则称活动i和活动j是相容的。活动安排问题就是要在所给的活动集合中选出最大的相容活动子集和。

其实主要关注的点就是前一个活动的结束时间大不大于后一个的开始时间,不大于就把后一个活动加入进去,活动1是直接加入的。

 

package shiyan.si;

import java.util.Scanner;
public class Huodong {
//    贪心算法1
public static int  greedselect(int[] a, int[] b, int n){
    int i,j=0,cnt=1;//活动1直接加入
    System.out.println("活动1进行("+a[0]+","+b[0]+")");
    for(i=1;i<n;i++){   //每次选择当前的左区间与上一个的右区间进行比较
        if(a[i]>b[j]){   //如果当前的开始时间大于上一个的结束时间,则加入到活动中
            System.out.println("活动"+(i+1)+"进行("+a[i]+","+b[i]+")");
            cnt++;
            j=i;
        }
    }
    return cnt;
}

    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        System.out.print("输入活动的数目:");
        int max=scanner.nextInt();
        int k,cont;
        int a[]=new int[max];
        int b[]=new int[max];

        for(k=0;k<max;k++){
            System.out.println("输入活动" + (k + 1) + "的开始时间和结束时间:");
            a[k]=scanner.nextInt();  //活动的开始时间
            b[k]=scanner.nextInt();  //活动的结束时间
        }
        cont=greedselect(a,b,max);
        System.out.println("能进行的活动一共有:"+cont);
    }
}

2.【背包问题】列有一堆物品S=(a1,a2…an),每一个物品ai都有对应的重量wi和价值vi。现在有一个背包,容量为C。现在要选择物品装入背包,所选物品重量不能超过背包容量,并使得背包里物品价值最大。与0-1背包不同的是,可以对物品进行分割,即可以只选取物品ai的一部分装入背包。

考虑的越多,越复杂,目前就这样简单实现吧。

package shiyan.si;

import java.util.Scanner;

public class T01bag {
    private static int ai;
    private static int C;
    private static int t;
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        System.out.println("请输入物品数量");
        ai=scanner.nextInt();
        int v[]=new int[ai];
        int w[]=new int[ai];
        System.out.println("请输入背包的容积");
        C=scanner.nextInt();
        for (int i = 0; i < ai; i++) {
            System.out.println("请输入对应物品" + (i + 1) + "的体积和价值");
            v[i]=scanner.nextInt();
            w[i]=scanner.nextInt();
        }
        double sum=max(ai,C,v,w);
        System.out.println("背包的总价值为:" + sum);
    }
    public static double max(int ai,int c,int v[],int w[]){
        double s[]=new double[ai];
        double sum=0;
        for (int i = 0; i < ai; i++) {
            s[i] = costeffective(v[i], w[i]);
        }
        for (int j=0;j<ai;j++){
            s[t]=0;
            sum+=value(v,w,s);
            if(C==0)break;
        }
        return sum;
    }
    public static double costeffective(double v,double w){
        double s = 0;
        try {
            s=w/v;
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("体积不能为0");
        }
        return s;
    }
    public static double value(int v[],int w[],double s[]){
        double va=0;
        double maxid=0;
        for (int i = 0; i < s.length; i++) {
            if(maxid<s[i]){
                maxid=s[i];
                t=i;
            }
        }
        if(v[t]<C){
            C=C-v[t];
            va=w[t];

        }else {
            va = C * s[t];
            C=0;
        }
        return va;
    }

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值