zoukankan      html  css  js  c++  java
  • 动态规划问题

    HDU-1284

    题目链接

    http://acm.hdu.edu.cn/showproblem.php?pid=1284

    这是一道背包类型的动态规划题目,题目意思是N块钱,可以有1,2,3元组成,问你有几种兑换方法,简单思考一下,假如说有n元钱,求f(n),f(n)= f(n-1)+f(n-2)+f(n-3)

    然后接下来递推或者递归都ok

    import java.util.*;
    public class Main {
    
        public static void main(String[] args) {
            Scanner in = new Scanner(System.in);
            int dp[][] = new int[4][32768];
            for (int i = 1; i < 4; i++) {
                dp[i][0] = 1;
            }
            for (int j = 1; j < 32768; j++) {
                dp[1][j] = 1;
            }
            for (int i = 1; i < 4; i++) {
                for (int j = 1; j < 32768; j++) {
                    if (i > j) {
                        dp[i][j] = dp[i - 1][j];
                    } else
                        dp[i][j] = dp[i - 1][j] + dp[i][j - i];
                }
            }
            while (in.hasNext()) {
                int n = in.nextInt();
                System.out.println(dp[3][n]);
            }
        }
    }

     

    求最长递增子序列,同样是动态规划的一种类型,代码复制自https://www.jianshu.com/p/ae71823744b3

    public class Main {
        
        public static int lis(int [] array)
        {
            int []lis = new int[array.length];
            int[] pre=new int[array.length];
            for(int i =0;i<array.length;i++)
            {
                lis[i]=1;
                pre[i]=i;
            }
             for (int j=1; j<array.length; j++) {  
                    for (int i=0; i<j; i++) {  
                        if (array[j]>array[i] && lis[j]<lis[i]+1){ //注意array[j]<array[i]+1这个条件,不能省略。  
                            lis[j] = lis[i] + 1; //计算以array[j]结尾的序列的最长递增子序列长度  
                            pre[j]=i;
                        }  
                    }  
                }  
            
            int max=0,index = 0;
            for(int k=0;k<lis.length;k++)
            {
                if(lis[k]>max){
                    max=lis[k];
                    index=k;
                }
            }
            System.out.println("最长递增子序列长度:"+max);
            Stack<Integer> stack=new Stack<Integer>();  
            while(index!=pre[index]){
                //System.out.print(array[index]+" ");   
                stack.push(array[index]);
                index=pre[index];       
            }
    
            if(index==pre[index])
            //  System.out.print(array[index]+" ");
                stack.push(array[index]);
            while(!stack.isEmpty())
                System.out.print(stack.pop()+" ");          
            return max;
        }
        
        
        public static void main(String[] args){
            int[] array={35, 36, 39, 3, 15, 27, 6, 42};
            lis(array);
        }
        
    }
     

    华为机试题合唱队(题目来自牛课网) 

    题目描述

    计算最少出列多少位同学,使得剩下的同学排成合唱队形

    说明:

    N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。 
    合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2,…,TK,   则他们的身高满足存在i(1<=i<=K)使得T1<T2<......<Ti-1<Ti>Ti+1>......>TK。 
    你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。 

    输入描述:

    整数N

    输出描述:

    最少需要几位同学出列

    示例1

    输入

    8
    186 186 150 200 160 130 197 200
    

    输出

    4
    import java.util.Scanner;
    
    public class Main {
        public static void main(String[] args) {
            Scanner in = new Scanner(System.in);
            while (in.hasNext()) {
                int num = in.nextInt();
                in.nextLine();
                int[] lis = new int[num];
    
                for (int i = 0; i < num; i++) {
                    lis[i] = in.nextInt();
                }
    
                int[] first = new int[num];
                int[] last = new int[num];
    
                for (int i = 0; i < last.length; i++) {
                    first[i] = 1;
                    last[i] = 1;
                }
    
                for (int i = 0; i < first.length; i++) {
                    for (int j = 0; j < i; j++) {
                        if (lis[i] > lis[j] && first[i] < first[j] + 1) {
                            first[i] = first[j] + 1;
                        }
                    }
                }
    
                for (int i = last.length - 1; i >= 0; i--) {
                    for (int j = last.length - 1; j > i; j--) {
                        if (lis[i] > lis[j] && last[i] < last[j] + 1) {
                            last[i] = last[j] + 1;
                        }
                    }
                }
    
                int max = 0;
                for (int i = last.length - 1; i >= 0; i--) {
                    //System.out.println(last[i]);
                    if (max < first[i] + last[i]) {
                        max = first[i] + last[i];
                    }
                }
                System.out.println(num - max + 1);
            }
        }
    }

    分析一下,这道题目要我们求的是一个最大递增子串加上最大递减字串

    所以我们可以正向求最大递增子串,再反向求最大递增字串,然后每个数字对应的最大递增字串长度和反向最大递增字串长度加起来值最大的就是我们要求的值,然后这个数字重复计入了字串长度

    所以总数-这个数字+1就是我们要的最少出列人数

  • 相关阅读:
    Java项目转换成Web项目
    Ajax模拟Form表单提交,含多种数据上传
    雪崩-隔离-熔断-降级-限流-sentinel,hystrix
    nacos集群搭建入门
    配置虚拟机的ip地址,dns地址以及hosts
    service network restart失败
    索引字段为空或者不为空的时候作为条件查询,索引是否起作用
    Invocation of init method failed; nested exception is java.lang.IllegalStateException: javax.websocket.server.ServerContainer not available
    ffmpeg+java视频转换基础示例
    字符串转换为指定的泛型对象
  • 原文地址:https://www.cnblogs.com/shineyoung/p/10504948.html
Copyright © 2011-2022 走看看