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: 构造最长递增子序列
题目描述
在“最长递增子序列”的基础上对代码进行改进,输出一条最长递增子序列。
输入
输出
样例输入 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]);
}
}
}