• 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
  • 相关阅读:
    [git 学习篇] git commit原理 --实践体会
    [git 学习篇]工作区和暂存区
    [git 学习篇] git文件版本回退再学习
    [git 学习篇]版本回退
    [git 学习篇] 修改文件
    [git 学习篇] 提交文件
    [git 学习篇] --创建git创库
    [测试框架学习] 测试框架的结构包含
    [python测试框架] http接口测试框架
    向SharePoint页面添加后台代码
  • 原文地址:https://www.cnblogs.com/lienus/p/4128290.html
Copyright © 2020-2023  润新知