真的就是一串C++11只有我一个傻der在用python35……
不过行少香啊……
DP策略 空间换时间
核心:记忆性,填表完成即找到最优解。
1.确定子问题
2.确定原问题和子问题间的递归式
3.确定存储子问题的数据结构
4.确定执行顺序
0-1背包
1 装箱问题
和“0-1背包”类似,就先写了,只不过是把背包中的二维数组表换成只计算“容量”的一维数组表。
python输入输出咱还在学
决策表使用两层循环,内层倒序(注意range步长用法),j 代表容量。这个解法的关键在于:逆向遍历 j,循环可以跳出,以优化
O
(
n
2
)
O(n^2)
O(n2)的时间复杂度。
v = int(input())
n = int(input())
box = [0] * n
dp = [0] * 40000
for i in range(n):
box[i] = int(input())
for i in range(n):
for j in range(v, 0, -1):
if box[i] > j:
break
dp[j] = max(dp[j], dp[j-box[i]]+box[i])
print(v - dp[v])
那就把0-1背包的解法也给出(正着算):
v = int(input())
n = int(input())
vol = [0] * n
for i in range(n):
vol[i] = int(input())
pri = [0] * n
for i in range(n):
pri[i] = int(input())
dp = [[0] * 2000] * 2000
for i in range(n):
for j in range(v):
if j < vol[i]:
dp[i][j] = dp[i-1][j]
else:
dp[i][j] = max(dp[i-1][j], dp[i-1][j-vol[i]]+pri[i])
print(j, dp[i][j])
print(dp[n - 1][v - 1])
(反着来):
v = int(input())
n = int(input())
vol = [0] * n
for i in range(n):
vol[i] = int(input())
pri = [0] * n
for i in range(n):
pri[i] = int(input())
dp = [[0] * 2000] * 2000
for i in range(n):
for j in range(v, -1, -1):
if j < vol[i]:
break
dp[i][j] = max(dp[i-1][j], dp[i-1][j-vol[i]]+pri[i])
print(dp[n - 1][v])
2 过河
这个我就很是难受……头发都揪没了……
python +
O
(
n
2
)
O(n^2)
O(n2)竟然内存超了。这个题使用正向,优化的方式是离散化。
这是一种离散化的方法:石头间距大于s~t连乘时,中间的步骤是可省的,所以只需取余就可以。
stamp = 1
for i in range(s, t+1):
stamp *= i
l = int(input())
s, t, m = map(int, input().split()) %使用map分别输入
sto = [int(i) for i in input().split()] % 输入一行的数组
d = [0] * m
for i in range(1, m):
d[i] = (sto[i] - sto[i-1]) % 2250 % 计算新的间距
for i in range(1, m):
sto[i] = sto[i-1] + d[i] % 更新石头位置
del d[:] % 尽力释放内存了
l = sto[m - 1] + t
dp = [m+1] * l
dp[0] = 0
for i in range(l):
for j in range(s, t+1):
if i-j < 0: break
elif dp[i - j] != m+1:
if i in sto:
dp[i] = min(dp[i], dp[i-j]+1)
else:
dp[i] = min(dp[i], dp[i-j])
print(dp[i-j:i]) % 测试
print(dp[l-1])
服了,我能看懂,但看不出差别
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int n, m, s, t, ans = 999999999;
int a[210];
int f[1000005];
int b[1000005];
int d[210];
int main()
{
scanf("%d", &n);
scanf("%d %d %d", &s, &t, &m);
for (int i = 1; i <= m; i++) scanf("%d", &a[i]);
sort(a + 1, a + 1 + m);
for (int i = 1; i <= m; i++) d[i] = (a[i] - a[i - 1]) % 2520;
for (int i = 1; i <= m; i++)
{
a[i] = a[i - 1] + d[i];
b[a[i]] = 1;
}
n = a[m];
memset(f, 127, sizeof(f));
f[s] = 0;
for (int i = 1; i <= n + t; i++)
{
for (int j = s; j <= t; j++)
{
if (i - j >= 0) f[i] = min(f[i], f[i - j] + b[i]);
}
}
for (int i = n; i < n + t; i++) ans = min(ans, f[i]);
printf("%d", ans);
return 0;
}