HDU5259(百度之星复赛1002)——弹吉他(DP)

来源:互联网 发布:python 静态属性 编辑:程序博客网 时间:2024/04/29 16:29

题目连接

题目分析

这是一道比较典型的DP题目,但是题目的状态数量比较多,转移数量也比较多,所以枚举起来会比较麻烦,所以可以用一个技巧就是可以预处理出所有的序列然后用序列枚举状态转移,这样会使代码简洁很多。

#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>using namespace std;typedef long long LL;const int MOD = 1e9 + 7;const int INF = 10000000;const int N = 5000 + 10;struct State {    int a[4], b[4]; //    void read() {        for(int i = 0; i < 4; i++) {            scanf("%d%d", &a[i], &b[i]);        }    }} s[N];int seq[30][4], dp[N][30];bool check(int b[], int q[]) { //序号大的手指所处的品位不能小于序号小的手指    for(int i = 1; i < 4; i++) {        if(b[q[i]] < b[q[i - 1]]) return false;    }    return true;}int calc(State& A, State& B, int q0[], int q1[]) {    int dis = 0;    for(int i = 0; i < 4; i++) {        dis += abs(A.a[q0[i]] - B.a[q1[i]]);        dis += abs(A.b[q0[i]] - B.b[q1[i]]);    }    return dis;}int main() {#ifdef TYH    freopen("in.txt", "r", stdin);#endif // TYH    int T, C = 1, n;    int A[4] = {0, 1, 2, 3};    int nq = 0;    do {        for(int i = 0; i < 4; i++) seq[nq][i] = A[i];        nq ++;    } while(next_permutation(A, A + 4));    scanf("%d", &T);    while(T--) {        printf("Case #%d:\n", C++);        scanf("%d" , &n);        for(int i = 1; i <= n; i++) {            s[i].read();        }        for(int i = 0; i < 4; i++)            s[0].b[i] = i + 1, s[0].a[i] = 0;        for(int i = 0; i < 24; i++) {            if(check(s[1].b, seq[i])) {                dp[1][i] = calc(s[0], s[1], seq[0], seq[i]);            } else {                dp[1][i] = INF;            }        }        for(int i = 2; i <= n; i++) {            for(int j = 0; j < 24; j++) {                dp[i][j] = INF;                if(!check(s[i].b, seq[j])) continue;                for(int k = 0; k < 24; k++) {                    if(dp[i - 1][k] == INF) continue;                    dp[i][j] = min(dp[i][j], dp[i - 1][k] + calc(s[i - 1], s[i], seq[k], seq[j]));                }            }        }        int ans = INF;        for(int i = 0; i < 24; i++) {            ans = min(ans, dp[n][i]);        }        printf("%d\n", ans);    }    return 0;}
0 0
原创粉丝点击