其他分享
首页 > 其他分享> > dp(武功秘籍)

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\n",sum-dp[v],dp[v]);
    }
    return 0;
}

 

标签:10,cnt,继承人,int,sum,秘籍,武功,dp
来源: https://www.cnblogs.com/lipu123/p/12194500.html