#4:初学者之身——5

Joyoi Mobile Service,第一维:阶段,第几时刻;第二第三维:不安定因素,两个服务员的位置;省略第四维:肯定在p[i-1]。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define rep(i, a, b) for (int i = a; i <= b; i++)
 4 #define inf 0x3f3f3f3f
 5 
 6 int n, m;
 7 int c[210][210], p[1010];
 8 int f[2][210][210];
 9 
10 int main() {
11     cin >> n >> m;
12     rep(i, 1, n)
13         rep(j, 1, n)
14             cin >> c[i][j];
15     rep(i, 1, m) cin >> p[i];
16     p[0] = 3;
17 
18     memset(f, 0x3f, sizeof(f));
19     f[0][1][2] = 0;
20 
21     rep(i, 1, m)
22         rep(x, 1, n)
23             rep(y, 1, n) {
24                 if (x != p[i-1] && y != p[i-1] && f[i-1&1][x][y] != inf) {
25                     int z = p[i-1];
26                     if (x != p[i] && y != p[i])    f[i&1][x][y] = min(f[i&1][x][y], f[i-1&1][x][y] + c[z][p[i]]);
27                     if (y != p[i] && z != p[i]) f[i&1][y][z] = min(f[i&1][y][z], f[i-1&1][x][y] + c[x][p[i]]);
28                     if (x != p[i] && z != p[i])    f[i&1][x][z] = min(f[i&1][x][z], f[i-1&1][x][y] + c[y][p[i]]);
29                     f[i-1&1][x][y] = inf;
30                 }
31             }
32             
33     int ans = inf;
34     rep(x, 1, n)
35         rep(y, 1, n)
36             ans = min(ans, f[m&1][x][y]);
37     cout << ans << endl;
38 
39     return 0;
40 }
View Code

洛谷1006,第一维:阶段,走到第几步;第二第三维:不安定因素,结尾位置;省略四维五维:有x坐标有步长可直接求y坐标。另外,一个格子只能走一次等价于走过一次还能走只不过值变成了0,会导致不如其他路线优秀。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define maxn 55
 4 #define rep(i, a, b) for (int i = a; i <= b; i++)
 5 
 6 int m, n;
 7 int a[maxn][maxn], f[2][maxn][maxn];
 8 
 9 int main() {
10     cin >> m >> n;
11     rep(i, 1, m) rep(j, 1, n)    cin >> a[i][j];
12 
13     rep(i, 0, n+m-3) {
14         int st = max(i+2-n, 1);
15         int ed = min(i+1, m);
16         rep(j, st, ed)
17             rep(k, st, ed) {
18                 if (j == k) {
19                     f[i+1&1][j][k] = max(f[i+1&1][j][k], f[i&1][j][k] + a[j][i+3-j]);//right
20                     f[i+1&1][j+1][k+1] = max(f[i+1&1][j+1][k+1], f[i&1][j][k] + a[j+1][i+2-j]);//down
21                 } else {
22                     f[i+1&1][j][k] = max(f[i+1&1][j][k], f[i&1][j][k] + a[j][i+3-j] + a[k][i+3-k]);//right
23                     f[i+1&1][j+1][k+1] = max(f[i+1&1][j+1][k+1], f[i&1][j][k] + a[j+1][i+2-j] + a[k+1][i+2-k]);//down    
24                 }
25                 if (j + 1 == k)    f[i+1&1][j+1][k] = max(f[i+1&1][j+1][k], f[i&1][j][k] + a[k][i+3-k]);//down&right
26                 else    f[i+1&1][j+1][k] = max(f[i+1&1][j+1][k], f[i&1][j][k] + a[k][i+3-k] + a[j+1][i+2-j]);//down&right
27                 if (k + 1 == j)    f[i+1&1][j][k+1] = max(f[i+1&1][j][k+1], f[i&1][j][k] + a[j][i+3-j]);//right&down
28                 else    f[i+1&1][j][k+1] = max(f[i+1&1][j][k+1], f[i&1][j][k] + a[j][i+3-j] + a[k+1][i+2-k]);//right&down
29 
30                 f[i&1][j][k] = 0;
31             }
32     }
33 
34     cout << f[n+m-2 & 1][m][m];
35     return 0;
36 }
View Code

CH Cookies,不能保证子结构后效性时说不定有排序贪心等性质,之后即可dp。下一步重头戏dp过程不会总结qwq

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define R(a) scanf("%d", &a)
 4 #define rep(i, a, b) for (int i = a; i <= b; i++)
 5 
 6 int n, m;
 7 int g[31], c[31], s[31];
 8 int f[31][5001], a[31][5001], b[31][5001], ans[31];
 9 
10 inline bool cmp(int a, int b) {
11     return g[a] > g[b];
12 }
13 
14 void print(int n, int m) {
15     if (!n)    return;
16     print(a[n][m], b[n][m]);
17     if (a[n][m] == n) {
18         rep(i, 1, n)    ans[c[i]]++;
19     } else {
20         rep(i, a[n][m]+1, n)    ans[c[i]] = 1;
21     }
22 }
23 
24 int main() {
25     R(n), R(m);
26     rep(i, 1, n)    R(g[i]), c[i] = i;
27     sort(c+1, c+1+n, cmp);
28 
29     memset(f, 0x3f, sizeof(f));
30     f[0][0] = 0;
31 
32     rep(i, 1, n) {
33         s[i] = s[i-1] + g[c[i]];
34         rep(j, i, m) {
35             f[i][j] = f[i][j-i];
36             a[i][j] = i;
37             b[i][j] = j-i;
38             rep(k, 0, i-1) {
39                 if (f[i][j] > f[k][j - (i-k)] + k * (s[i] - s[k])) {
40                     f[i][j] = f[k][j - (i-k)] + k * (s[i] - s[k]);
41                     a[i][j] = k;
42                     b[i][j] = j - (i-k);
43                 }
44             }
45         }
46     }
47 
48     printf("%d
", f[n][m]);
49     print(n, m);
50     rep(i, 1, n)    printf("%d ", ans[i]);
51 
52     return 0;
53 }
View Code

Joyoi数字组合,初学者背包裸题。

 1 #include <cstdio>
 2 
 3 int n, m, v[101];
 4 int f[10001];
 5 
 6 int main() {
 7     scanf("%d%d", &n, &m);
 8     for (int i = 1; i <= n; i++)
 9         scanf("%d", &v[i]);
10     
11     f[0] = 1;
12     for (int i = 1; i <= n; i++)
13         for (int j = m; j >= v[i]; j--) {
14             f[j] += f[j-v[i]];
15         }
16 
17     printf("%d", f[m]);
18     return 0;
19 }
View Code

BZOJ2914,有一点点像背包?就是得把题目的本质规律弄清楚就会了吧。

 1 #include <cstdio>
 2 #include <cctype>
 3 #define ri readint()
 4 #define gc getchar()
 5 #define rep(i, a, b) for (int i = a; i <= b; i++)
 6 #define W(a) printf("%d
", a);
 7 #define maxn 10005
 8 
 9 int n, h[maxn];
10 int ans;
11 int re[maxn], p, t;
12 bool f[maxn];
13 
14 inline int readint() {
15     int x = 0, s = 1, c = gc;
16     while (c <= 32)    c = gc;
17     if (c == '-')    s = -1, c = gc;
18     for (; isdigit(c); c = gc)
19         x = x * 10 + c - 48;
20     return x * s;
21 }
22 
23 int main() {
24     n = ri;
25     rep(i, 1, n)    h[i] = ri;
26     f[h[n]+1] = true;
27 
28     rep(i, 0, h[n]+1) {
29         //height i is existed but not stable!
30         if (f[i] && i != h[t+1]) {
31             ans = h[t];
32             break;
33         }
34         if (i == h[t+1]) {
35             if (!f[i]) {//add this as a base
36                 re[++p] = h[t+1];
37                 f[i] = true;
38             }
39             t++;
40         }
41         if (f[i]) {
42             rep(j, 1, p)
43                 f[re[j] + i] = true;
44         }
45     }
46 
47     W(ans);
48     rep(i, 1, p)    W(re[i]);
49     return 0;
50 }
View Code
原文地址:https://www.cnblogs.com/AlphaWA/p/10348145.html