zoukankan      html  css  js  c++  java
  • 【ASC 23】G. ACdream 1429 Rectangular Polygon --DP

    题意:有很多棍子,从棍子中选出两个棍子集合,使他们的和相等,求能取得的最多棍子数。

    解法:容易看出有一个多阶段决策的过程,对于每个棍子,我们有 可以不选,或是选在第一个集合,或是选在第二个集合 这三种决策。因为两个集合最后的和要相等,那么令一个集合为正,另一个为负,那么最后和为0,我们用偏移0的量来作为状态之一。

    dp[i][j]表示前 i 个 偏移量为 j 的最大棍子数,因为每根棍最长为200,所以偏移量最多为+-20000,所以在+-20000之间枚举,最多100*40000

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <string>
    #include <vector>
    using namespace std;
    #define N 30007
    
    int dp[105][60004],path[105][60004];
    int a[105];
    
    int main()
    {
        freopen("polygon.in","r",stdin);
        freopen("polygon.out","w",stdout);
        int n,i,j;
        while(scanf("%d",&n)!=EOF)
        {
            memset(dp,-1,sizeof(dp));
            int sum = 0;
            for(i=1;i<=n;i++) {
                scanf("%d",&a[i]);
                sum += a[i];
            }
            int low = N-sum, high = N+sum;
            dp[0][N] = 0;
            for(i=1;i<=n;i++) {
                for(j=low;j<=high;j++) {
                    if(dp[i-1][j] != -1 && dp[i][j] < dp[i-1][j]) {
                        dp[i][j] = dp[i-1][j];
                        path[i][j] = j;
                    }
                    if(dp[i-1][j-a[i]] != -1 && dp[i][j] < dp[i-1][j-a[i]]+1) {
                        dp[i][j] = dp[i-1][j-a[i]]+1;
                        path[i][j] = j-a[i];
                    }
                    if(dp[i-1][j+a[i]] != -1 && dp[i][j] < dp[i-1][j+a[i]]+1) {
                        dp[i][j] = dp[i-1][j+a[i]]+1;
                        path[i][j] = j+a[i];
                    }
                }
            }
            printf("%d
    ",dp[n][N]);
            int now = N,pre;
            vector<int> UP,DOWN;
            for(i=n;i>=1;i--) {
                pre = path[i][now];
                if(now > pre) UP.push_back(now-pre);
                if(pre > now) DOWN.push_back(pre-now);
                now = pre;
            }
            int x = 0, y = 0;
            for(i=0;i<UP.size();i++) {
                printf("%d %d
    ",x,y);
                x += UP[i];
                printf("%d %d
    ",x,y);
                y++;
            }
            for(i=0;i<DOWN.size();i++) {
                printf("%d %d
    ",x,y);
                x -= DOWN[i];
                printf("%d %d
    ",x,y);
                y++;
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    104.Maximum Depth of Binary Tree
    103.Binary Tree Zigzag Level Order Traversal
    102.Binary Tree Level Order Traversal
    101.Symmetric Tree
    100.Same Tree
    99.Recover Binary Search Tree
    98.Validate Binary Search Tree
    97.Interleaving String
    static静态初始化块
    serialVersionUID作用
  • 原文地址:https://www.cnblogs.com/whatbeg/p/4275518.html
Copyright © 2011-2022 走看看