算法训练 - dp

仅供代码 仅供代码 仅供代码

摘花生

import java.io.*;
import java.util.*;
public class Main{
	public static void main(String[] args) {
		In in = new In(System.in);
		PrintWriter out =  new PrintWriter(System.out);
		int T = in.nextInt();
		for(int i = 0;i < T;i++) {
			int r = in.nextInt();
			int c = in.nextInt();
//			int[][] arr = new int[r][c];
			int[][] dp = new int[r+1][c+1];
			for(int j = 1;j<=r;j++) {
				for(int k = 1;k<=c;k++) {
//					arr[j][k] = in.nextInt();
					dp[j][k] = max(dp[j-1][k],dp[j][k-1]) + in.nextInt(); 
				}
			}
			out.println(dp[r][c]);
		}
		out.close();
	}
	
	static int max(int a,int b) {return a>b?a:b;}
	
	static class In{
		BufferedReader reader;
		StringTokenizer token;
		public In(InputStream in) {
			reader = new BufferedReader(new InputStreamReader(in));
		}
		String next() {
			if(token == null || !token.hasMoreTokens()) {
				try {
					token = new StringTokenizer(reader.readLine());
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			return token.nextToken();
		}
		int nextInt() {return Integer.parseInt(next());}
	}
}	

最低通行费

import java.io.*;
import java.util.*;
public class Main {
	public static void main(String[] args) {
		In in = new In(System.in);
		PrintWriter out = new PrintWriter(System.out);
		int n = in.nextInt();
		int dp[] = new int[n+1];
		dp[0] = Integer.MAX_VALUE;
		dp[1] = in.nextInt();
		for(int i = 2;i <= n;i++) dp[i] = dp[i-1]+in.nextInt();
		for(int i = 2;i <= n;i++)
			for(int j = 1;j <= n;j++)
				dp[j] = min(dp[j],dp[j-1]) + in.nextInt();
		out.print(dp[n]);
		out.close();
	}
	
//	static int max(int a,int b) {return a>b?a:b;}
	static int min(int a,int b) {return a<b?a:b;}
	
	static class In{
		BufferedReader reader;
		StringTokenizer token;
		public In(InputStream in) {
			reader = new BufferedReader(new InputStreamReader(in));
		}
		String next() {
			if(token==null || !token.hasMoreTokens()) {
				try {
					token = new StringTokenizer(reader.readLine());
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			return token.nextToken();
		}
		int nextInt() {return Integer.parseInt(next());}
	}
}

方格取数

import java.io.*;
import java.util.*;
public class Main {
	public static void main(String[] args) {
		In in = new In(System.in);
		PrintWriter out = new PrintWriter(System.out);
		int n = in.nextInt();
		int[][] arr = new int[n+1][n+1];
		int[][][] dp = new int[2*n+2][n+1][n+1];
		int m = 1;
		while(true) {
			int a = in.nextInt();
			int b = in.nextInt();
			int c = in.nextInt();
			if(a==0 && b==0 && c==0)break;
			arr[a][b] = c;
		}
		for(int k = 2;k <= n + n;k++) {
			for(int i1 = 1;i1 <= n;i1++) {
				for(int i2 = 1;i2 <= n;i2++) {
					int j1 = k-i1,j2 = k-i2;
					if(j1>0 && j1<=n && j2>0 && j2<=n) {
						int t = arr[i1][j1];
						if(i1!=i2) t += arr[i2][j2];
						dp[k][i1][i2] = max(dp[k][i1][i2],dp[k-1][i1-1][i2-1]);
						dp[k][i1][i2] = max(dp[k][i1][i2],dp[k-1][i1-1][i2]);
						dp[k][i1][i2] = max(dp[k][i1][i2],dp[k-1][i1][i2-1]);
						dp[k][i1][i2] = max(dp[k][i1][i2],dp[k-1][i1][i2]);
						dp[k][i1][i2] += t;
					}
				}
			}
		}
		out.print(dp[2*n][n][n]);
		out.close();
	}
	
	static int max(int a,int b) {return a>b?a:b;}
	
	static class In{
		BufferedReader reader;
		StringTokenizer token;
		public In(InputStream in) {
			reader = new BufferedReader(new InputStreamReader(in));
		}
		String next() {
			if(token==null || !token.hasMoreTokens()) {
				try {
					token = new StringTokenizer(reader.readLine());
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			return token.nextToken();
		}
		int nextInt() {return Integer.parseInt(next());}
	}
}	

怪盗基德的滑翔翼

import java.io.*;
import java.util.StringTokenizer;

public class Main {
	public static void main(String[] args) {
		In in = new In(System.in);
		PrintWriter out = new PrintWriter(System.out);
		int K = in.nextInt();
		for(int i = 0;i < K;i++) {
			int n = in.nextInt();
			int[] arr = new int[n+1];
			int[] dp = new int[n+1];
			for(int j = 1;j <= n;j++) {
				arr[j] = in.nextInt();
			}
			
			int max = 0;
			//从左至右求最长上升子序列
			for(int j = 1;j <= n;j++) {
				dp[j] = 1;
				for(int k = 1;k < j;k++) {
					if(arr[j] > arr[k]) {
						dp[j] = max(dp[j],dp[k]+1);
					}
				}
				max = max(dp[j],max);
			}
			
			//从右至左求最长上升子序列
			for(int j = n;j >= 1;j--) {
				dp[j] = 1;
				for(int k = n;k > j;k--) {
					if(arr[j] > arr[k]) {
						dp[j] = max(dp[j],dp[k]+1);
					}
				}
				max = max(max,dp[j]);
			}
			out.println(max);
		}
		out.close();
	}
	
	static int max(int a,int b) {return a>b?a:b;}
	
	static class In{
		BufferedReader reader;
		StringTokenizer token;
		public In(InputStream in) {
			reader = new BufferedReader(new InputStreamReader(in));
		}
		String next() {
			if(token==null || !token.hasMoreTokens()) {
				try {
					token = new StringTokenizer(reader.readLine());
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			return token.nextToken();
		}
		int nextInt() {return Integer.parseInt(next());}
	}
}

登山

import java.io.*;
import java.util.*;
public class Main {
	public static void main(String[] args) {
		In in = new In(System.in);
		PrintWriter out = new PrintWriter(System.out);
		int n = in.nextInt();
		int arr[] = new int[n+1];
		int dp1[] = new int[n+1];
		int dp2[] = new int[n+1];
		for(int i =1;i <= n;i++)arr[i]  =in.nextInt();
		//正常的最长上升子序列
		for(int i = 1;i<=n;i++) {
			dp1[i] = 1;
			for(int j = 1;j<i;j++) {
				if(arr[i] > arr[j])dp1[i] = max(dp1[i],dp1[j]+1);
			}
		}
		//从右至左
		for(int i = n;i > 0;i--) {
			for(int j = n;j > i;j--) {
				if(arr[i] > arr[j])dp2[i] = max(dp2[i],dp2[j]+1);
			}
		}
		int max = 0;
		for(int i = 1;i <= n;i++) {
			max  = max(max,dp1[i] + dp2[i]);
		}
		out.print(max);
		out.close();
	}
	
	static int max(int a,int b) {return a>b?a:b;}
	
	static class In{
		BufferedReader reader;
		StringTokenizer token;
		public In(InputStream in) {
			reader = new BufferedReader(new InputStreamReader(in));
		}
		String next() {
			if(token==null || !token.hasMoreTokens()) {
				try {
					token = new StringTokenizer(reader.readLine());
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			return token.nextToken();
		}
		int nextInt() {return Integer.parseInt(next());}
	}
}

合唱队形

import java.io.*;
import java.util.StringTokenizer;
//同登山 最长上升子序列和下降子序列之间最大和
//这里为 n-最大和 
//应该可以优化(挖坑,先ac
public class Main {
	public static void main(String[] args) {
		In in = new In(System.in);
		PrintWriter out = new PrintWriter(System.out);
		int n = in.nextInt();
		int arr[] = new int[n];
		int dp1[] = new int[n];
		int dp2[] = new int[n];
		for(int i =0;i < n;i++)arr[i] = in.nextInt();
		for(int i = 0;i < n;i++) {
			dp1[i] = 1;
			for(int j = 0;j < i;j++) {
				if(arr[i] > arr[j])dp1[i] = max(dp1[i],dp1[j]+1);
			}
		}
		for(int i = n-1;i>=0;i--) {
			for(int j = n-1;j>i;j--) {
				if(arr[i] > arr[j])dp2[i] = max(dp2[i],dp2[j]+1);
			}
		}
		int max = 0;
		for(int i = 0;i < n;i++) {
			max = max(max,dp1[i] + dp2[i]);
		}
		out.print(n-max);
		out.close();
	}
	
	static int max(int a ,int b) {return a>b?a:b;}
	
	static class In{
		BufferedReader reader;
		StringTokenizer token;
		public In(InputStream in) {
			reader = new BufferedReader(new InputStreamReader(in));
		}
		String next() {
			if(token==null || !token.hasMoreTokens()) {
				try {
					token = new StringTokenizer(reader.readLine());
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			return token.nextToken();
		}
		int nextInt() {return Integer.parseInt(next());}
	}
}

再加一个dp外的

整数子串

暴力大法显然超时
大佬分析为小学奥数
我:??!
在这里插入图片描述

import java.util.Scanner;
public class Main {
	public static void main(String[] args) {
		char[] c = new Scanner(System.in).next().toCharArray();
		long count = 0;
		//判断单个数字是否能被4整除
		for(int i = 0;i < c.length;i++) {
			if((c[i]-'0')%4 == 0)count++;
		}
		//一个数的末尾两位数能被4整除,那么这个数能被4整除
		for(int i = 1;i < c.length;i++) {
			if(((c[i-1]-'0')*10 + (c[i]-'0'))%4 == 0)count += i;
		}
		System.out.println(count);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值