动态规划-蓝桥杯-健身
这是一个完全背包的题,可以利用完全背包来解决。
//package com.js.datastructure.recursion.蓝桥.国特训练营.动态规划线性DP;import java.util.ArrayList;
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int[] kkk = new int[21];kkk[0] = 1;for (int i = 1; i < 21; i++) {kkk[i] = kkk[i-1] * 2;}//1~n天中选择一些日子健身//有m个健身计划,第i个健身计划,需要2^ki天,获得健身增益si//有q天有其他安排//int n = scanner.nextInt();int m = scanner.nextInt();int q = scanner.nextInt();int[] t = new int[q];for (int i = 0; i < q; i++) {t[i] = scanner.nextInt();}int[] k = new int[m];int[] s = new int[m];//记录值for (int i = 0; i < m; i++) {k[i] = kkk[scanner.nextInt()];s[i] = scanner.nextInt();}//定义dp[i]为间隔天数为i时的最大收益数,转化为完全背包,正序遍历long[] dp = new long[n+1];for (int i = 0; i < m; i++) {if(k[i] > n){continue;}dp[k[i]] = Math.max(s[i],dp[k[i]]);for (int j = 0; j < n+1; j++) {if(dp[j] != 0 && j + k[i] < n+1){dp[j + k[i]] = Math.max(dp[j] + s[i],dp[j + k[i]]);}}}//处理dp数组,满足题目中的int now = 0;for (int i = 0; i < n + 1; i++) {if(dp[i] != 0){now = i;}else {dp[i] = dp[now];}}//把时间段摘出来,进行填充ArrayList<Integer> time = new ArrayList<>();time.add(t[0] - 1);for (int i = 1; i < q; i++) {time.add(t[i] - t[i-1] - 1);}time.add(n - t[q-1]);long ans = 0;for(int tt : time){ans = ans + dp[tt];}System.out.println(ans);}
}