zoukankan      html  css  js  c++  java
  • DP训练

    1.HDU 4540

    简单DP

    #include <cstdio>
    #include <iostream>
    using namespace std;
    
    int main() {
    //    freopen("data3.txt", "r", stdin);
        int dp[30][20], pos[30][20];
        int n, k;
        while (~scanf("%d%d", &n, &k)) {
            memset(dp, 0x7f, sizeof(dp));
            for (int i = 0; i < n; i++)
                for (int j = 0; j < k; j++)
                    scanf("%d", &pos[i][j]);
            for (int i = 0; i < k; i++)
                dp[0][i] = 0;
            for (int i = 1; i < n; i++)
                for (int j = 0; j < k; j++) {
                    for (int d = 0; d < k; d++)
                        dp[i][j] = min(dp[i][j],
                                dp[i - 1][d] + abs(pos[i - 1][d] - pos[i][j]));
                }
            int ans = 0x3fffffff;
            for (int i = 0; i < k; i++)
                ans = min(ans, dp[n - 1][i]);
            printf("%d
    ", ans);
        }
        return 0;
    }

    2.HDU 1078

    记忆化,类似树从根节点向上dp

    #include<cstdio>
    #include <iostream>
    #include<cstring>
    #include<cmath>
    using namespace std;
    #define N 105
    int dir[4][2] = { 1, 0, -1, 0, 0, 1, 0, -1 };
    int dp[N][N], map[N][N];
    bool mark[N][N], vis[N][N];
    int n, k;
    inline bool check(int x, int y) {
        return x >= 0 && x < n && y >= 0 && y < n;
    }
    void DP(int a, int b) {
        mark[a][b] = 1;
        vis[a][b] = 1;
        int x, y;
        for (int i = 0; i < 4; i++) {
            for (int j = 1; j <= k; j++) {
                x = a + dir[i][0] * j;
                y = b + dir[i][1] * j;
                if (check(x, y) && !vis[x][y] && map[x][y] > map[a][b]) {
                    if (mark[x][y]) {
                        dp[a][b] = max(dp[a][b], dp[x][y] + map[a][b]);
                    } else {
                        DP(x, y);
                        dp[a][b] = max(dp[a][b], dp[x][y] + map[a][b]);
                    }
                }
            }
        }
        if (dp[a][b] == 0)
            dp[a][b] = map[a][b];
        vis[a][b] = 0;
    }
    int main() {
    //    freopen("data3.txt", "r", stdin);
        int i, j;
        while (scanf("%d%d", &n, &k)) {
            if (n == -1 && k == -1)
                break;
            memset(mark, 0, sizeof(mark));
            memset(dp, 0, sizeof(dp));
            memset(vis, 0, sizeof(vis));
            for (i = 0; i < n; ++i) {
                for (j = 0; j < n; ++j) {
                    scanf("%d", &map[i][j]);
                }
            }
            mark[0][0] = 1;
            DP(0, 0);
            printf("%d
    ", dp[0][0]);
        }
        return 0;
    }

    3. 携程第二场

    二维背包的思想,枚举每段长度,来维护dp[i][j]表示两段长度分别为 i 和 j 能否被拼出来。最后通过dp[i][j]为1的判断形成三角形和最大的面积。

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <cmath>
    using namespace std;
    
    double deal(double a, double b, double c) {
        double p = (a + b + c) / 2.0;
        return sqrt(p * (p - a) * (p - b) * (p - c));
    }
    bool check(int a, int b, int c) {
        if (a + b <= c)
            return 0;
        if (a + c <= b)
            return 0;
        if (b + c <= a)
            return 0;
        return 1;
    }
    int f[1005][1005];
    int dp[50];
    int main() {
        int n;
        while (scanf("%d", &n) == 1) {
            if (n == 0)
                break;
            int totlen = 0;
            memset(f, 0, sizeof(f));
            for (int i = 0; i < n; i++) {
                scanf("%d", &dp[i]);
                totlen += dp[i];
            }
            f[0][0] = 1;
            for (int i = 0; i < n; i++) {
                for (int k = 1000; k >= 0; k--) {
                    for (int j = k; j >= 0; j--) {
                        if (k - dp[i] >= 0 && f[k - dp[i]][j])
                            f[k][j] = 1;
                        if (j - dp[i] >= 0 && f[k][j - dp[i]])
                            f[k][j] = 1;
                    }
                }
            }
            double ans = 0;
            for (int i = 0; i <= 1000; i++) {
                for (int j = 0; j <= i; j++) {
                    if (f[i][j] && check(i, j, totlen - i - j))
                        ans = max(ans, deal(i, j, totlen - i - j));
                }
            }
            if (!ans)
                puts("-1");
            else
                printf("%d
    ", (int) (ans * 1000) / 10);
        }
        return 0;
    }
  • 相关阅读:
    Ajax请求过程中显示“进度”的简单实现
    Asp.net 图片文件防盗链介绍
    ASP.NET MVC验证
    MVC文件上传
    MVC文件上传-使用jQuery.FileUpload和Backload组件实现文件上传
    使用jQuery.FileUpload插件和服Backload组件自定义上传文件夹
    使用jQuery.FileUpload和Backload自定义控制器上传多个文件
    使用jQuery.FileUpload插件和Backload组件裁剪上传图片
    CSS3 多列
    CSS3 2D转换 动画
  • 原文地址:https://www.cnblogs.com/updateofsimon/p/3452305.html
Copyright © 2011-2022 走看看