zoukankan      html  css  js  c++  java
  • zoj2059(经典dp)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1059

    分析:dp[i][j]表示前i个石头组成两座塔高度差为j的较低塔最大高度

    状态转移:

    每次石头都有三种方法:

    1.放在高塔上:dp[i][j]=max(dp[i][j+t],dp[i][j]);低塔不变

    2.放在低塔上:1)dp[i][j]=max(dp[i][j-t],dp[i][j]);低塔仍是较低塔

                        2)dp[i][j]=max(dp[i][t-j],dp[i][j]);低塔超过高塔

    3.低塔高塔都不放

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <cstdlib>
    #include <vector>
    #include <set>
    #include <map>
    #define LL long long
    #define inf 1<<30
    #define mod 1000000007
    using namespace std;
    int dp[105][2010];
    int main()
    {
        int n,t;
        while(scanf("%d",&n)>0)
        {
            if(n<0)break;
            memset(dp,-1,sizeof(dp));
            dp[0][0]=0;
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&t);
                memcpy(dp[i],dp[i-1],sizeof(dp[i-1]));
                for(int j=0;j<=2000;j++)
                {
    
                    if(dp[i-1][j]!=-1)
                    {
                        int x=dp[i-1][j];
                        int y=dp[i-1][j]+j;
                        if(x+t<=y)
                        {
                            dp[i][j-t]=max(dp[i][j-t],x+t);
                        }
                        else
                        {
                            dp[i][t-j]=max(dp[i][t-j],y);
                        }
                        dp[i][j+t]=max(dp[i][j+t],x);
                    }
                }
            }
            if(dp[n][0]<=0)puts("Sorry");
            else printf("%d
    ",dp[n][0]);
        }
    }
    View Code

    为了节省空间,还可以用滚动数组来实现dp

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <cstdlib>
    #include <vector>
    #include <set>
    #include <map>
    #define LL long long
    #define inf 1<<30
    #define mod 1000000007
    using namespace std;
    int dp[2][2010];
    int main()
    {
        int n,t;
        while(scanf("%d",&n)>0)
        {
            if(n<0)break;
            memset(dp,-1,sizeof(dp));
            dp[0][0]=0;
            int pre=0,now=1;
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&t);
                memcpy(dp[now],dp[pre],sizeof(dp[now]));
                for(int j=2000;j>=0;j--)
                {
                    if(dp[pre][j]!=-1)
                    {
                        int x=dp[pre][j];
                        int y=dp[pre][j]+j;
                        if(x+t<=y)
                        {
                            dp[now][j-t]=max(dp[now][j-t],x+t);
                        }
                        else
                        {
                            dp[now][t-j]=max(dp[now][t-j],y);
                        }
                        dp[now][j+t]=max(dp[now][j+t],x);
                    }
                }
                swap(pre,now);
            }
            if(dp[pre][0]<=0 )puts("Sorry");
            else printf("%d
    ",dp[pre][0]);
        }
    }
    View Code
  • 相关阅读:
    Qt共享内存实现进程间通信(QSharedMemory)
    Qt5.5制作简单的屏幕截图程序
    006--C++动态内存(简介)
    005--C++字符
    004--C++11的初始化方式
    003--sizeof的使用
    002--C++程序的创建
    001--基础知识准备
    Qt5.5连接MySQL
    vue-cli中如何创建并引入自定义组件
  • 原文地址:https://www.cnblogs.com/lienus/p/4128290.html
Copyright © 2011-2022 走看看