问题 A: 最长递增子序列
注意数组大小,可能有测试数据范围导致的运行错误
import java.util.Scanner;
public class Main {
static int[] a=new int[1010];//存原数据
static int[] b=new int[1010];//b[i]为以a[i]为单调递增子序列最后一个元素时所得的最长单调子序列的和
static int[] pre=new int[1010];//存前一个的位置
static int[] str=new int[1010];
static int n;
static int maxLen;
static void solve(){
b[1]=1;
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;
}
maxLen=b[1];
for(int i=2;i<=n;i++){
maxLen= Math.max(b[i], maxLen);
}
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
n=sc.nextInt();
for(int i=1;i<=n;i++){
a[i]=sc.nextInt();
}
solve();
System.out.println(maxLen);
}
}
}
问题 B: 构造最长递增子序列
这个没啥好说的,沿着上一题的思路来就是
import java.util.Scanner;
public class Main {
static int[] a=new int[1010];//存原数据
static int[] b=new int[1010];//b[i]为以a[i]为单调递增子序列最后一个元素时所得的最长单调子序列的和
static int[] pre=new int[1010];//存前一个的位置
static int[] str=new int[1010];
static int n;
static int maxLen;
static int mark;
static void solve(){
b[1]=1;
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;
}
maxLen=b[1];
mark=1;
for(int i=2;i<=n;i++){
if(b[i]>maxLen){
maxLen=b[i];
mark=i;
}
}
int j=mark;
int i=maxLen;
while(pre[j]>0){
str[i--]=a[j];
j=pre[j];
}
str[i]=a[j];
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
boolean flag=false;
n=sc.nextInt();
for(int i=1;i<=n;i++){
a[i]=sc.nextInt();
}
solve();
for(int i=1;i<=maxLen;i++){
if(!flag){
System.out.print(str[i]);
flag=true;
}else{
System.out.print(" "+str[i]);
}
}
System.out.println();
// System.out.println(maxLen);
}
}
}
问题 C: 出列人数
也没啥好说的,典型的LIS
import java.util.Scanner;
public class Main {
static int[] a=new int[1010];//存原数据
static int[] b=new int[1010];//b[i]为以a[i]为单调递增子序列最后一个元素时所得的最长单调子序列的和
static int[] pre=new int[1010];//存前一个的位置
static int[] str=new int[1010];
static int n;
static int maxLen;
static int mark;
static void solve(){
b[1]=1;
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;
}
maxLen=b[1];
mark=1;
for(int i=2;i<=n;i++){
if(b[i]>maxLen){
maxLen=b[i];
mark=i;
}
}
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
boolean flag=false;
n=sc.nextInt();
for(int i=1;i<=n;i++){
a[i]=sc.nextInt();
}
solve();
System.out.println(n-maxLen);
}
}
}
问题 D: 0-1背包问题
典中典
import java.util.Arrays;
import java.util.Scanner;
public class Main {
static int n;
static int c;
static int[] w=new int[1010];
static int[] v=new int[1010];
static int[][] s=new int[1010][1010];
static int[] arr = new int[1010];
static void solve(int[]w,int[]v,int[]arr,int n,int c){
int jmax=Math.min(c,w[n]-1);//预防数组越界
//先填最后一行
for(int j=0;j<=jmax;j++){
s[n][j]=0;//装不下
}
for(int j=w[n];j<=c;j++){
s[n][j]=v[n];//装得下
}
//至此最后一行填完
//接下来DP开始
for(int i=n-1;i>=1;i--){
jmax=Math.min(c,w[i]-1);
for(int j=0;j<=jmax;j++){
s[i][j]=s[i+1][j];//装不下
}
for(int j=w[i];j<=c;j++){
s[i][j]=Math.max(s[i+1][j],s[i+1][j-w[i]]+v[i]);//装得下
}
}
//至此DP结束
int mark=c;
for(int i=1;i<n;i++){
if(s[i][mark]!=s[i+1][mark]){
arr[i]=1;
mark=mark-w[i];
} else {
arr[i]=0;
}
}
arr[n]=s[n][mark]>0?1:0;
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
n=sc.nextInt();
c=sc.nextInt();
for(int i=1;i<=n;i++){//价值
v[i]=sc.nextInt();
}
for(int i=1;i<=n;i++){//重量
w[i]=sc.nextInt();
}
solve(w,v,arr,n,c);
System.out.println(s[1][c]);
for(int i=1;i<=n;i++){
System.out.print(arr[i]);
}
System.out.println();
Arrays.fill(w,0);
Arrays.fill(v,0);
Arrays.fill(arr,0);
// for(int i=0;i<=n;i++){
// for(int j=0;j<=c;j++){
// System.out.print(s[i][j]+" ");
// }
// System.out.println();
// }//测试输出
}
}
}
问题 E: XP的午餐
import java.util.Arrays;
import java.util.Scanner;
public class Main {
static int n;
static int c;
static int[] w=new int[1010];
static int[] v=new int[1010];
static int[][] s=new int[1010][1010];
static void solve(int[]w,int[]v,int n,int c){
int jmax=Math.min(c,w[n]-1);//预防数组越界
//先填最后一行
for(int j=0;j<=jmax;j++){
s[n][j]=0;//装不下
}
for(int j=w[n];j<=c;j++){
s[n][j]=v[n];//装得下
}
//至此最后一行填完
//接下来DP开始
for(int i=n-1;i>=1;i--){
jmax=Math.min(c,w[i]-1);
for(int j=0;j<=jmax;j++){
s[i][j]=s[i+1][j];//装不下
}
for(int j=w[i];j<=c;j++){
s[i][j]=Math.max(s[i+1][j],s[i+1][j-w[i]]+v[i]);//装得下
}
}
//至此DP结束
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
c=sc.nextInt();
n=sc.nextInt();
for(int i=1;i<=n;i++){//价值
w[i]=sc.nextInt();
v[i]=sc.nextInt();
}
solve(w,v,n,c);
System.out.println(s[1][c]);
Arrays.fill(w,0);
Arrays.fill(v,0);
}
}
}
问题 F: 补充能量
import java.util.Arrays;
import java.util.Scanner;
public class Main {
static int n;
static int c;
static int[] w=new int[1010];
static int[] v=new int[1010];
static int[][] s=new int[1010][1010];
static void solve(int[]w,int[]v,int n,int c){
int jmax=Math.min(c,w[n]-1);//预防数组越界
//先填最后一行
for(int j=0;j<=jmax;j++){
s[n][j]=0;//装不下
}
for(int j=w[n];j<=c;j++){
s[n][j]=v[n];//装得下
}
//至此最后一行填完
//接下来DP开始
for(int i=n-1;i>=1;i--){
jmax=Math.min(c,w[i]-1);
for(int j=0;j<=jmax;j++){
s[i][j]=s[i+1][j];//装不下
}
for(int j=w[i];j<=c;j++){
s[i][j]=Math.max(s[i+1][j],s[i+1][j-w[i]]+v[i]);//装得下
}
}
//至此DP结束
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
n=sc.nextInt();
c=sc.nextInt();
for(int i=1;i<=n;i++){//重量
w[i]=sc.nextInt();
}
for(int i=1;i<=n;i++){//价值
v[i]=sc.nextInt();
}
solve(w,v,n,c);
System.out.println(s[1][c]);
Arrays.fill(w,0);
Arrays.fill(v,0);
// for(int i=0;i<=n;i++){
// for(int j=0;j<=c;j++){
// System.out.print(s[i][j]+" ");
// }
// System.out.println();
// }//测试输出
}
}
}
问题 G: 最少硬币(经典的贪心应用)
import java.util.Scanner;
public class Main {
static int[] coins={1,5,10,25};
static int solve(int n){
int num=0;
if(n<=0)return 0;
for(int i=3;i>=0;i--){
num+=n/coins[i];
n=n%coins[i];
if(n==0)break;
}
return num;
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
while (sc.hasNext()){
int n=sc.nextInt();
System.out.println(solve(n));
}
}
}
问题 H: 图书排序
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
public class Main {
public static class book implements Comparable<book>{
String name;
int sales;
double price;
public book(String s, int parseInt, double parseDouble) {
super();
name=s;
sales=parseInt;
price=parseDouble;
}
@Override
public int compareTo(book o) {
if(sales>o.sales){
return -1;
} else if(sales==o.sales){
if(price>o.price)return 1;
else if(price==o.price)return 0;
else return -1;
} else return 1;
}
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
List<book>books=new ArrayList<book>();
int n=Integer.parseInt(sc.nextLine());
while(n>0){
n--;
String[] msg=sc.nextLine().split(" ");
books.add(new book(msg[0], Integer.parseInt(msg[1]), Double.parseDouble(msg[2])));
}
Collections.sort(books);
for(book b:books){
System.out.print(b.name+" "+b.sales+" ");
System.out.printf("%.2f\n",b.price);
}
}
}
醉后不知天在水,满船清梦压星河
因为牙疼深夜上分