813最大平均值和的分组 (leetcode动态规划题)
一开始并无思路怎么写,试着套用一下动态规划的思路进行解析.
设dp[i][k]为i
个数字分为k
个子数组的最大平均值和的分组
最初思维只知道dp[i][k]
可由dp[i][k-1]
推导而来,可使用动态规划,但写不出动态规划的关键步骤
看题解写出来的
-
d
p
[
i
]
[
k
]
dp[i][k]
dp[i][k]为第
i
位数,分割为k
个子数组 - 状态转移方程: d p [ i ] [ k ] = m a x ( d p [ j ] [ k − 1 ] + ( n u m s [ j ] + . . . + n u m s [ i − 1 ] ) / ( i − j − 1 ) ) dp[i][k]=max(dp[j][k-1] +(nums[j]+...+nums[i-1])/(i-j-1)) dp[i][k]=max(dp[j][k−1]+(nums[j]+...+nums[i−1])/(i−j−1)) (1 < j < i)
- 边界条件: d p [ i ] [ 1 ] = d p [ 1 , . . , i ] / i dp[i][1] = dp[1,..,i] / i dp[i][1]=dp[1,..,i]/i
public double largestSumOfAverages(int[] nums, int K) {
int n = nums.length;
double[] presum = new double[n+1];
double[][] dp = new double[n+1][K+1];
for(int i = 1; i <= n; i++){
presum[i] = presum[i-1] + nums[i-1];
dp[i][1] = presum[i] / i;
}
for(int i = 1; i <= n; i++){
for(int k = 2; k <= K; k++){
for(int j = 0; j < i; j++){
dp[i][k]=Math.max(dp[i][k],dp[j][k-1]+(presum[i]-presum[j])/(i-j));
}
}
}
return dp[n][K];
}
蓝桥骑士(蓝桥动态规划题)
等同于最长递增子序列
朴素的线性DP
线性dp
问题,由于比较熟悉,直接写出动态规划的重要步骤,但是只过了一个测试用例,之后的测试用例超时,还需优化.
- 状态表示:
d
p
[
i
]
dp[i]
dp[i]表示以第
i
个数为结尾的最大递增序列 - 状态转移方程式: d p [ i ] = m a x ( d p [ i ] , d p [ j ] + 1 ) dp[i] = max(dp[i], dp[j] +1) dp[i]=max(dp[i],dp[j]+1) (0 <= j < i)
- 边界条件, d p [ 1 ] = 1 dp[1] = 1 dp[1]=1,只有一个数的时候,最长的递增子数列也为1.
public class Main(){
public static main(String[] args){
Scanner scan = new Scanner(System.in);
//在此输入您的代码...
int n = scan.nextInt();
long[] arr = new long[n];
// System.out.println(n);
for(int i = 0; i < n; i++){
arr[i] = scan.nextInt();
// System.out.println("arr[i]"+arr[i]);
}
long[] dp = new long[n];
dp[0] = 1;
for(int i = 1; i < n; i++){
for(int j = 0; j < i; j++){
if(arr[i] > arr[j]){
dp[i] = Math.max(dp[i], dp[j]+1);
}
}
}
System.out.println(dp[n-1]);
scan.close();
}
}
数据范围:
1
<
a
r
r
.
l
e
n
g
t
h
<
3
∗
1
0
5
1 < arr.length < 3 * 10^5
1<arr.length<3∗105,
1
<
a
r
r
[
i
]
<
1
0
9
1 < arr[i] < 10^9
1<arr[i]<109
数据范围很大,时间复杂度为
O
(
n
2
)
O(n^2)
O(n2)时会超时,arr[i]
还有可能超出int最大范围
不
会
优
化
,
再
多
想
想
不会优化,再多想想
不会优化,再多想想