动态规划试题
cin >> A[i];
}
dp[0] = A[0];
for(int i=1; i < n; i++){
dp[i] = max(A[i],dp[i-1]+A[i]);
}
sort(dp,dp+n);
cout << dp[n-1] << endl;
return 0;
}
6
-2 11 -4 13 -5 -2
输出:20
}
for(int i=n-1; i >=0; i--){
for(int j=0; j <= i; j++){
dp[i][j] = max(dp[i+1][j],dp[i+1][j+1]) + a[i][j];
}
}
cout << dp[0][0] << endl;
return 0;
}
②
//最大连续子序列和
}
for(int i=1; i <= n; i++){
for(int j=0; j <= m; j++){
for(int k=0; k <= s[i] && k*v[i] <= j; k++){
f[i][j] = max(f[i][j],f[i-1][j-k*v[i]]+k*w[i]);
}
}
}
cout << f[n][m];
int n,m;
cin >> n >> m;
for(int i=1; i <= m; i++){
cin >> a[i] >> b[i];
}
for(int i=1; i<=m; i++){
for(int j=a[i]; j <=n; j++){
f[j] = max(f[j],f[j-a[i]]+b[i]);
}
}
cout << f[n];
return 0;
}
01背包
实现代码:采药-传送门
输入:
70 3
71 100
69 1
1 2
输出:3
每个数组遍历一遍
#include<iostream>
#include<algorithm>
using namespace std;
int a[101],b[101];
int f[10001];
int dp[maxn][maxn];
int main(){
完全背包
[无限量]的采摘药输入:
70 3
71 100
69 1
1 2
输出:140
每个数组在满足条件,可以遍历多次
#include<iostream>
#include<algorithm>
using namespace std;
int f[100001];
int a[10001],b[10001];
int main(){
int main()
{
cin >> n >> m;
int cnt = 0;
for (int i = 1; i <= n; i ++ )
{
int a, b, s;
cin >> a >> b >> s;
int k = 1;
while (k <= s)
{
cnt ++ ;
v[cnt] = a * k;
w[cnt] = b * k;
using namespace std;
int f[20005],w[35];
int main()
{
int v,n;
cin>>v&;=n;i++)cin>>w[i];
for(int i=1;i<=n;i++){
for(int j=v;j>=w[i];j--){
f[j]=max(f[j],f[j-w[i]]+w[i]);
s -= k;
k *= 2;
}
if (s > 0)
{
cnt ++ ;
v[cnt] = a * s;
w[cnt] = b * s;
}
}
n = cnt;
for (int i = 1; i <= n; i ++ )
for (int j = m; j >= v[i]; j -- )
f[j] = max(f[j], f[j - v[i]] + w[i]);
}
}
cout<<v-f[v];
return 0;}
f[j]=max(f[j],f[j-w[i]]+w[i]);
f[j]为:当总容量为j时,不放第i件物品,所能装的最大体积。
f[j-w[i]]+w[i]为:当总容量为j时,放了第i件物品后,所能装的最大体积。(即j减去第i件物品体积的容量能装的最大体积+第i件物品的体积。w[i]为第i件物品体积)
int main(){
int n,m;
cin >> n >> m;
for(int i=1; i <= m; i++){
cin >> a[i] >> b[i];
}
for(int i=1; i <=m; i++){
for(int j=n; j >= a[i]; j--){
f[j] = max(f[j],f[j-a[i]]+b[i]);
if(A[i] > A[j] && (dp[j] + 1) > dp[i]){
dp[i] = dp[j] + 1;
}
}
ans = max(ans,dp[i]);
}
cout << ans << endl;
return 0;
}
④
//最长公共子序列
给定两个长度分别为N和M的字符串A和B,求既是A的子序列又是B的子序列的字符串长度最长是多少。
动态规划
装箱问题(01背包):
有一个箱子容量为VV(正整数,0≤V≤20000),同时有n个物品(0<n≤30,每个物品有一个体积(正整数)。要求n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。
24 6
8 3 12 7 9 7
输出:0
#include<iostream>
#include<cstdio>
}
for(int i=1; i <= m; i++){
for(int j=n; j >= k[i]; j--){
f[j] = max(f[j],f[j-k[i]]+k[i]*v[i]);
}
}
cout << f[n];
return 0;
}
多重背包
有N种物品和一个容量是V的背包。
第ii种物品最多有sisi件,每件体积是vivi,价值是wiwi。
输入样例:
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
输出样例:
30
#include<iostream>
#include<algorithm>
const int MAXV = 10010;
using namespace std;
int dp[MAXV][MAXV];
int main(){
int n;
输入样例
4 5
1 2 3
2 4 1
3 4 3
4 5 2
输出样例:
10
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 12010, M = 2010;
int n, m;
int v[N], w[N];
int f[M];
const int maxn = 110;
int n,m;
int v[maxn],w[maxn],s[maxn];
int f[maxn][maxn];
int main(){
cin >> n >> m;
for(int i=1; i <= n; i++){
cin >> v[i] >> w[i] >> s[i];
从第2行到第m+1行,第jj行给出了编号为j-1的物品的基本数据,每行有2个非负整数v p(其中vv表示该物品的价格(v≤10000),p表示该物品的重要度(1-5)
输出格式
1个正整数,为不超过总钱数的物品的价格与重要度乘积的总和的最大值(<100000000)。
输入:
1000 5
800 2
400 5
#include<iostream>
#include<algorithm>
using namespace std;