一、递推求解
N阶楼梯上楼问题
#include<cstdio>
using namespace std;
int F[91];
int main() {
F[1] = 1;
F[2] = 2;
for (int i = 3; i <= 90; i++)
F[i] = F[i-1] + F[i-2];
int n;
while (scanf("%d", &n) != EOF)
printf("%d\n", F[n]);
return 0;
}
不容易系列之一
#include<cstdio>
using namespace std;
long long F[91];
int main() {
F[1] = 0;
F[2] = 1;
for (int i = 3; i <= 20; i++)
F[i] = (i-1)*F[i-1] + (i-1)*F[i-2];
int n;
while (scanf("%d", &n) != EOF)
printf("%lld\n", F[n]);
return 0;
}
二、最长递增子序列(LIS)
拦截导弹
#include <cstdio>
#include <algorithm>
using namespace std;
int list[26];
int dp[26];
int main() {
int n;
while (scanf("%d", &n) != EOF) {
for (int i = 1; i <=n ; i++)
scanf("%d", &list[i]);
for (int i = 1; i <= n; i++) {
int tmax = 1;
for (int j = 1; j < i; j++) {
if (list[j] >= list[i]) {
tmax = max(tmax, dp[j]+1);
}
}
dp[i] = tmax;
}
int ans = 1;
for (int i = 1; i <= n; i++) {
if (dp[i] > ans)
ans = dp[i];
}
printf("%d\n", ans);
}
return 0;
}
三、最长公共子序列(LCS)
Coincidence
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int dp[101][101];
int main() {
char s1[101], s2[101];
while (scanf("%s%s", s1, s2) != EOF) {
int l1 = strlen(s1);
int l2 = strlen(s2);
for (int i = 0; i <= l1; i++)
dp[i][0] = 0;
for (int j = 0; j <= l2; j++)
dp[0][j] = 0;
for (int i = 1; i <= l1; i++) {
for (int j = 1; j <= l2; j++) {
if (s1[i-1] != s2[j-1])
dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
else
dp[i][j] = dp[i-1][j-1] + 1;
}
}
printf("%d\n", dp[l1][l2]);
}
return 0;
}
四、动态规划问题分析举例
搬寝室
![](https://img-blog.csdn.net/20180625164907415?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2JlYXNoYXBlcl8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
#include <cstdio>
#include <algorithm>
using namespace std;
const int Max = 0x0fffffff;
int list[2001];
int dp[1001][2001];
int main() {
int n, k;
while (scanf("%d%d", &n, &k) != EOF) {
for (int i = 1; i <= n; i++)
scanf("%d", &list[i]);
sort(list+1, list+n+1);
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= k; j++) {
dp[j][i] = Max;
}
}
for (int i = 0; i <= n; i++)
dp[0][i] = 0;
for (int i = 1; i <= k; i++) {
for (int j = 2*i; j <= n; j++) {
dp[i][j] = min(dp[i][j-1], dp[i-1][j-2] + (list[j]-list[j-1]) * (list[j]-list[j-1]) );
}
}
printf("%d\n", dp[k][n]);
}
return 0;
}
五、背包
0-1背包
采药
#include <cstdio>
#include <algorithm>
using namespace std;
struct E {
int w;
int v;
} list[101];
int dp[101][1001];
int main() {
int s, n;
while (scanf("%d%d", &s, &n) != EOF) {
for (int i = 1; i <= n; i++)
scanf("%d%d", &list[i].w, &list[i].v);
for (int i = 1; i <= n; i++)
dp[0][i] = 0;
for (int i = 1; i <= n; i++) {
for (int j = s; j >= list[i].w; j--) {
dp[i][j] = max(dp[i-1][j], dp[i-1][j-list[i].w] + list[i].v);
}
for (int j = list[i].w-1; j >= 0; j--)
dp[i][j] = dp[i-1][j];
}
printf("%d\n", dp[n][s]);
}
return 0;
}
#include <cstdio>
#include <algorithm>
using namespace std;
struct E {
int w;
int v;
} list[101];
int dp[1001];
int main() {
int s, n;
while (scanf("%d%d", &s, &n) != EOF) {
for (int i = 1; i <= n; i++)
scanf("%d%d", &list[i].w, &list[i].v);
for (int i = 1; i <= n; i++)
dp[i] = 0;
for (int i = 1; i <= n; i++) {
for (int j = s; j >= list[i].w; j--) {
dp[j] = max(dp[j], dp[j-list[i].w] + list[i].v);
}
for (int j = list[i].w-1; j >= 0; j--)
dp[j] = dp[j];
}
printf("%d\n", dp[s]);
}
return 0;
}
完全背包
Piggy-Bank
#include <cstdio>
#include <algorithm>
using namespace std;
const int INF = 0x7fffffff;
struct E {
int w;
int v;
} list[501];
int dp[10001];
int main() {
int T;
scanf("%d", &T);
while (T--) {
int s, tmp;
scanf("%d%d", &tmp, &s);
s -= tmp;
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d%d", &list[i].v, &list[i].w);
for (int i = 0; i <= s; i++)
dp[i] = INF;
dp[0] = 0;
for (int i = 1; i <= n; i++) {
for (int j = list[i].w; j <= s; j++) {
if (dp[j-list[i].w] != INF)
dp[j] = min(dp[j], dp[j-list[i].w] + list[i].v);
}
}
if (dp[s] != INF)
printf("The minimum amount of money in the piggy-bank is %d.\n", dp[s]);
else
printf("This is impossible.\n");
}
return 0;
}
多重背包
珍惜现在,感恩生活
#include <cstdio>
#include <algorithm>
using namespace std;
struct E {
int v;
int w;
} list[2001];
int dp[101];
int main() {
int T;
scanf("%d", &T);
while (T--) {
int s, n;
scanf("%d%d", &s, &n);
int cnt = 0;
for (int i = 1; i <= n; i++) {
int v, w, k;
scanf("%d%d%d", &v, &w, &k);
int c = 1;
while (k-c > 0) {
k -= c;
list[++cnt].v = c*v;
list[cnt].w = c*w;
c *= 2;
}
list[++cnt].v = v*k;
list[cnt].w = w*k;
}
for (int i = 1; i <= s; i++)
dp[i] = 0;
for (int i = 1; i <= cnt; i++) {
for (int j = s; j >= list[i].v; j--) {
dp[j] = max(dp[j], dp[j-list[i].v] + list[i].w);
}
}
printf("%d\n", dp[s]);
}
return 0;
}