HOJ 2091 Chess(三维简单DP)

Chess
My Tags (Edit)
Source : Univ. of Alberta Local Contest 1999.10.16
Time limit : 1 sec Memory limit : 32 M
Submitted : 244, Accepted : 100
The Association of Chess Monsters (ACM) is planning their annual team match up against the rest of the world. The match will be on 30 boards, with 15 players playing white and 15 players playing black. ACM has many players to choose from, and they try to pick the best team they can. The ability of each player for playing white is measured on a scale from 1 to 100 and the same for playing black. During the match a player can play white or black but not both. The value of a team is the total of players’ abilities to play white for players designated to play white and players’ abilities to play black for players designated to play black. ACM wants to pick up a team with the highest total value.
Input
Input consists of a sequence of lines giving players’ abilities. Each line gives the abilities of a single player by two integer numbers separated by a single space. The first number is the player’s ability to play white and the second is the player’s ability to play black. There will be no less than 30 and no more than 1000 lines on input.
There are multiple test cases. Each case will be followed by a single line containing a “*”.
Output
Output a single line containing an integer number giving the value of the best chess team that ACM can assemble.
Sample Input
87 84
66 78
86 94
93 87
72 100
78 63
60 91
77 64
77 91
87 73
69 62
80 68
81 83
74 63
86 68
53 80
59 73
68 70
57 94
93 62
74 80
70 72
88 85
75 99
71 66
77 64
81 92
74 57
71 63
82 97
76 56
*
Sample Output
2506

如果能想到用三维表示状态,就很容易了
dp[i][j][k]表示到第i个人已经选了j个人去打白选了k个人去打黑
那么dp[i][j][k]只有三种情况,在第i个人要么不选他,要么选他打白,要么选他打黑

#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <algorithm>

using namespace std;
int dp[1005][20][20];
int a[1005];
int b[1005];
char c[1005];
char d[1005];
int fun(char *a)
{
    int len=strlen(a);
    int num=0;
    for(int i=0;i<len;i++)
    {
        num+=(a[i]-'0')*(int)(pow(10,(len-i-1)));
    }
    return num;

}
int main()
{
    while(scanf("%s",c)!=EOF)
    {
        scanf("%s",d);
        int cnt=0;
        while(true)
        {
            a[++cnt]=fun(c);
            b[cnt]=fun(d);
            scanf("%s",c);
            if(c[0]=='*')
                break;
            else
                scanf("%s",d);
        }
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=cnt;i++)
        {
            for(int j=0;j<=15;j++)
            {
                for(int k=0;k<=15;k++)
                {
                    if(j+k>i)
                        continue;
                    if(!j&&k)
                        dp[i][j][k]=max(dp[i-1][j][k],dp[i-1][j][k-1]+b[i]);
                    else if(j&&!k)
                        dp[i][j][k]=max(dp[i-1][j][k],dp[i-1][j-1][k]+a[i]);
                    else if(!j&&!k)
                        dp[i][j][k]=dp[i-1][j][k];
                    else
                        dp[i][j][k]=max(dp[i-1][j][k],max(dp[i-1][j-1][k]+a[i],dp[i-1][j][k-1]+b[i]));
                }
            }
        }
        printf("%d\n",dp[cnt][15][15]);
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值