• dp(武功秘籍)


    众所周知,太吾绘卷是非常爱(niu)你(bi)的国产武侠游戏,里面有一个继承系统,当你死后可以在你的子孙中挑选一个继承人,用他的人物继续进行游戏。当你挑选继承人的时候一定会挑选能力最强,天赋最高的那一个来继承。这样你培养的时候也会重点培养天赋最高的那一个。某zf大侠有两个继承人,第一个天赋很高,第二个天赋比较平庸,zf大侠想重点培养第一个继承人,但是又怕第二继承人觉得不公平,所以他会在尽量公平的基础上来重点培养第一个继承人。Zf大侠有n种秘籍,每种秘籍都能提升某个人一定的能力,请你帮zf大侠决定怎么培养继承人吧。Input本题有多组输入,每组数据第一行输入由整数N(0 < N <= 50)组成,表示秘籍的种类。接下来N行,每行两个整数V(0 当N为负数时程序结束。Output每组数据输出一行,包含两个数字A和B,分别带表两个继承人最终获得的能力大小(一开始两个继承人的能力都为0),A和B用空格分开。Sample Input

    2
    10 1
    20 1
    3
    10 1 
    20 2
    30 1
    -1

    Sample Output

    20 10
    40 40

    解析:dp[sum/2]是其全部的一半(能取到的话)或者为其最小的那一分

    #include<bits/stdc++.h> 
    using namespace std;
    const int maxn=5e5+10;
    int dp[250005];
    int a[10005];
    int main()
    {
        int n;
        while(~scanf("%d",&n)&&n>=0){
            memset(a,0,sizeof(a));
            memset(dp,0,sizeof(dp));
            int x,y,sum=0;
            int cnt=0;
            for(int i=1;i<=n;i++){
                scanf("%d%d",&x,&y);
                sum+=x*y;
                int t=1;
                while(y>=t){
                    a[cnt]=x*t;
                    cnt++;
                    y-=t;
                    t*=2;
                }
                if(y>0){
                    a[cnt]=x*y;
                }
            }
            int v=sum/2;
            for(int i=0;i<=cnt;i++){
                for(int j=v;j>=a[i];j--){
                    dp[j]=max(dp[j],dp[j-a[i]]+a[i]);
                }
            }
            printf("%d %d
    ",sum-dp[v],dp[v]);
        }
        return 0;
    }
  • 相关阅读:
    TSQL循环打印一年中所有的日期(WHILE循环)
    给Table加字段的SQL
    [正则表达式]前台JS得到控件ID (该控件被其它控件包住了)
    1.SQL Server中批量更新Object的Owner 2.附加数据库
    转:动态LINQ的几种方法
    转:查看LINQ生成SQL语句的几种方法
    TrimZero方法
    Oracle关联更新语法(TSQL中的update...from)
    Table之间的空隙或Table与父控件之间的空隙怎么去掉?
    自动完成带来的麻烦
  • 原文地址:https://www.cnblogs.com/lipu123/p/12194500.html
Copyright © 2020-2023  润新知