2022年春季学期《算法分析与设计》练习10

1457: 最长递增子序列

题目描述

给出一个序列a1,a2,a3,a4,a5,a6,a7...an,求它的一个子序列(设为s1,s2,...sn),使得这个子序列满足这样的性质:s1<s2<s3<...<sn并且这个子序列的长度最长。输出这个最长子序列的长度,要求时间复杂度为O(n2)。

输入

每组输入包括两行,第一行为序列长度n,第二行为序列。

输出

输出最长递增子序列的长度。

样例输入 Copy

7
1 7 3 5 9 4 8

样例输出 Copy

4
import java.util.Scanner;
 
public class Main{
     
 
public static void main(String[] args) {
    Scanner cin = new Scanner(System.in);  
    while(cin.hasNext()) {
     int n=cin.nextInt();
     
     int a[]=new int[n+1];
     int b[]=new int[n+1];
     for(int i=1;i<=n;i++) {
         a[i]=cin.nextInt();
     }
     int result=solve(a,b,n);
     System.out.println(result);
      
         
}
     
 
 
}
public static  int solve(int []a,int []b,int n){
    b[1]=1;
    int max=b[1];
    int maxlen;
    for(int i=2;i<=n;i++){
        maxlen=0;
        for(int j=i-1;j>=1;j--){
            if(a[j]<a[i]&&b[j]>maxlen){
                maxlen=b[j];
            }
        }
        b[i]=maxlen+1;
        if(b[i]>max){
            max=b[i];
             
        }
         
    }
    return max;
     
     
}
 
}

1460: 构造最长递增子序列

题目描述

在“最长递增子序列”的基础上对代码进行改进,输出一条最长递增子序列。

输入

每组输入包括两行,第一行为序列长度n,第二行为序列。

输出

输出最长递增子序列中的任意一条即可。

样例输入 Copy

7
1 7 3 4 9 2 3

样例输出 Copy

1 3 4 9
#include<iostream>
 using namespace std;
  int solve(int a[],int b[],int n,int c[],int pre[]){
    b[1]=1;
    int max=b[1];
    int maxlen;
    for(int i=2;i<=n;i++){
        maxlen=0;
        for(int j=i-1;j>=1;j--){
            if(a[j]<a[i]&&b[j]>maxlen){
                maxlen=b[j];
                pre[i]=j;
            }
        }
        b[i]=maxlen+1;
        if(b[i]>max){
            max=b[i];
             
        }
         
    }
    maxlen=b[1];
     
    int lab=0;
    for(int i=2;i<=n;i++){
        if(b[i]>maxlen){
            maxlen=b[i];
            lab=i;
        }
    }
    int i=lab;
    int j=maxlen;
    int num=maxlen;
    while(num>0){
        c[j]=a[i];
        j--;
        i=pre[i];
        num--;
    }
     
    return max;
     
}
 
 
 
 int main(){
    int n=0;
    while(cin>>n) {
     int a[n+1];
     int b[n+1];
     int c[n+1];
     int pre[n+1];
     for(int i=1;i<=n;i++) {
        cin>> a[i];
     }
int r=solve(a,b,n,c,pre);
     for(int i=1;i<=r;i++){
         cout << c[i];
         cout <<" ";
     }
      
     cout <<endl; 
         
}
}

1465: 0-1背包问题

题目描述

给定n种物品和一个背包,物品i的重量是Wi,其价值为Vi,背包的容量为C。如何选择装入背包的物品,可以使得装入背包中物品的总价值最大?

输入

每组输入包括三行,
第一行包括物品个数n,以及背包容量C。
第二、三行包括两个一维数组,分别为每一种物品的价值和重量。

输出

输出包括两行,第一行为背包的最大总价值,第二行为所选取的物品。
例如:最大总价值=15,物品选取策略为11001。数据保证答案唯一。

样例输入 Copy

5 10
6 3 5 4 6
2 2 6 5 4

样例输出 Copy

15
11001
import java.util.Scanner;
 
public class Main{
     
 
public static void main(String[] args) {
    Scanner cin = new Scanner(System.in);  
    while(cin.hasNext()) {
     int n=cin.nextInt();
      int c=cin.nextInt();
     int w[]=new int[n+5];
     int v[]=new int[n+5];
     int m[][]=new int[n+1][c+1];
     int x[]=new int[n+5];
     for(int i=1;i<=n;i++) {
         v[i]=cin.nextInt();
     }
     for(int i=1;i<=n;i++) {
         w[i]=cin.nextInt();
     }
     solve(w,v,c,n,m);
     traceback(m,w,c,n,x);
     System.out.println(m[1][c]);
     for(int i=1;i<=n;i++){
         System.out.print(x[i]);
     }
     System.out.println();
      
    }
     
 
 
}
public static void solve(int w[],int v[],int c,int n,int m[][]){
    int jmax=Math.min(w[n]-1,c);
    for(int j=0;j<=jmax;j++){
        m[n][j]=0;
    }
    for(int j=w[n];j<=c;j++){
        m[n][j]=v[n];
    }
    for(int i=n-1;i>=1;i--){
        jmax=Math.min(w[i]-1,c);
        for(int j=0;j<=jmax;j++){
            m[i][j]=m[i+1][j];
        }
        for(int j=w[i];j<=c;j++){
            m[i][j]=Math.max(m[i+1][j],m[i+1][j-w[i]]+v[i]);
        }
    }
}
public static void traceback(int m[][],int w[],int c,int n,int x[]){
    for(int i=1;i<n;i++){
        if(m[i][c]==m[i+1][c])
            x[i]=0;
        else {
            x[i]=1;
            c=c-w[i];
        }
         
    }
    x[n]=(m[n][c]>0?1:0);
}
}
   

1540: XP的午餐

题目描述

XP每天都会思考一个问题,今天午餐去哪里吃?这是一个很重要的问题,这会影响到他下午的体力值。他的午餐预算是M元,现在有N种菜品,每一种菜品的价格和能够提供的体力值已知(每种菜品只能选择一次),请问如何选择菜品能够让XP下午的体力值最大呢?

输入

多组输入
第一行:M元和菜品数量N。
接下来N行,每一行两个整数,分别表示每一种菜品的价格(vi)和能够获得的体力值(wi)。
(0<N<=20,0<=M<=1000)(0<=vi<=50,0<=wi<=100)

输出

最大体力值。

样例输入 Copy

10 5
1 5
2 4
3 3
4 2
5 1

样例输出 Copy

14
#include <bits/stdc++.h>
#include<algorithm>
using namespace std;
void solve(int w[],int v[],int c,int n,int **m){
    int jmax=min(w[n]-1,c);
    for(int j=0;j<=jmax;j++){
        m[n][j]=0;
    }
    for(int j=w[n];j<=c;j++){
        m[n][j]=v[n];
    }
    for(int i=n-1;i>=1;i--){
        jmax=min(w[i]-1,c);
        for(int j=0;j<=jmax;j++){
            m[i][j]=m[i+1][j];
        }
        for(int j=w[i];j<=c;j++){
            m[i][j]=max(m[i+1][j],m[i+1][j-w[i]]+v[i]);
        }
    }
}   
int main(){
int c=0;
 
    while(cin>>c) {
        int n=0;
     cin>>n;
     int w[n+5];
     int v[n+5];
     int **m=new int*[c+1];
     for(int i=0;i<n+1;i++){
        m[i]=new int[c+1];
     }
      
     int j=1,k=1;
     for(int i=0;i<2*n;i++) {
         if(i%2==0){
        cin>> w[j];
         j++;
         }
         else{
        cin >>v[k];
         k=k+1;
         }
     }
     
     solve(w,v,c,n,m);
      
     cout<<m[1][c]<<endl;
      
    }
     
}

1749: 最少硬币

题目描述

假设有4种硬币,它们的面值分别为1分、5分、10分和25分。
现在要找给顾客n分钱。
请问怎样找零钱才能使给顾客的硬币个数最少?
输出所需最少硬币的枚数。

输入

输入需要找给顾客的零钱n(单位:分)。

输出

输出所需最少硬币的枚数。

样例输入 Copy

8
10
63

样例输出 Copy

4
1
6
#include <bits/stdc++.h>
using namespace std;
int main(){
int n=0;
        while(cin>>n){
         
            int a[4];
            int s=0;
            a[0]=1;a[1]=5;a[2]=10;a[3]=25;
            for(int i=3;i>=0;){
                if(a[i]<=n){
                    s++;
                    n-=a[i];
                }else
                    i--;
            }
            cout<<s<<endl;
        }
    }

1468: 图书排序

题目描述

某图书销售管理系统需要对图书(Book)进行排序,每一本图书包含书名(bookName)、销量(bookSales)、价格(bookPrice)等属性,要求先按照销量由大到小排序,对于销量相同的图书再按照价格由小到大排序。

输入

每组输入包括两个部分,第一部分为书的数量n,
接下来n行则为n本书的信息。 按顺序输入书名(不超过20个字)、销量、价格。

输出

输出排序后的信息,每个属性用空格隔开

样例输入 Copy

7
C++程序设计 120 25.00
软件工程 96 48.00
高等数学 80 32.50
算法分析与设计 96 54.00
离散数学 96 28.00
计算机网络 96 36.00
操作系统 115 45.00

样例输出 Copy

C++程序设计 120 25.00
操作系统 115 45.00
离散数学 96 28.00
计算机网络 96 36.00
软件工程 96 48.00
算法分析与设计 96 54.00
高等数学 80 32.50
import java.util.Scanner;
public class Main {
    public static String[] bn;
    public static int[] bs;
    public static float[] bp;
    public static int n;
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner scan=new Scanner(System.in);
        while(scan.hasNext()){
            n=scan.nextInt();
            bn=new String[n];
            bs=new int[n];
            bp=new float[n];
            for(int i=0;i<n;i++){
                bn[i]=scan.next();
                bs[i]=scan.nextInt();
                bp[i]=scan.nextFloat();
            }
            slove();
        }
    }
    public static void slove(){
        int t=bs[0];
        for(int i=0;i<n;i++)
            for(int j=0;j<n-i-1;j++){
                if(bs[j+1]>bs[j]){
                    String s=bn[j];
                    bn[j]=bn[j+1];
                    bn[j+1]=s;
                     
                    int t1=bs[j];
                    bs[j]=bs[j+1];
                    bs[j+1]=t1;
                     
                    float t2=bp[j];
                    bp[j]=bp[j+1];
                    bp[j+1]=t2;
                }
                else if(bs[j]==bs[j+1])
                    if(bp[j]>bp[j+1]){
                        String s=bn[j];
                        bn[j]=bn[j+1];
                        bn[j+1]=s;
                         
                        int t1=bs[j];
                        bs[j]=bs[j+1];
                        bs[j+1]=t1;
                         
                        float t2=bp[j];
                        bp[j]=bp[j+1];
                        bp[j+1]=t2;
                    }
            }
        for(int i=0;i<n;i++){
            System.out.print(bn[i]+" "+bs[i]+" ");
            System.out.printf("%.2f\n",bp[i]);
            }
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

君临๑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值