Codeforces859C

来源:互联网 发布:淘宝分流比例设置 编辑:程序博客网 时间:2024/06/02 05:30
C. Pie Rules
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

You may have heard of the pie rule before. It states that if two people wish to fairly share a slice of pie, one person should cut the slice in half, and the other person should choose who gets which slice. Alice and Bob have many slices of pie, and rather than cutting the slices in half, each individual slice will be eaten by just one person.

The way Alice and Bob decide who eats each slice is as follows. First, the order in which the pies are to be handed out is decided. There is a special token called the "decider" token, initially held by Bob. Until all the pie is handed out, whoever has the decider token will give the next slice of pie to one of the participants, and the decider token to the other participant. They continue until no slices of pie are left.

All of the slices are of excellent quality, so each participant obviously wants to maximize the total amount of pie they get to eat. Assuming both players make their decisions optimally, how much pie will each participant receive?

Input

Input will begin with an integer N (1 ≤ N ≤ 50), the number of slices of pie.

Following this is a line with N integers indicating the sizes of the slices (each between 1 and 100000, inclusive), in the order in which they must be handed out.

Output

Print two integers. First, the sum of the sizes of slices eaten by Alice, then the sum of the sizes of the slices eaten by Bob, assuming both players make their decisions optimally.

Examples
input
3141 592 653
output
653 733
input
510 21 10 21 10
output
31 41
Note

In the first example, Bob takes the size 141 slice for himself and gives the decider token to Alice. Then Alice gives the size 592 slice to Bob and keeps the decider token for herself, so that she can then give the size 653 slice to herself.

题意:有两个人分n块披萨,每块披萨有一点量,Bob拥有第一回合优先权,每回合有优先权的可以选择这块披萨给自己或者给对方,如果给自己,下回合对方拥有优先权,否则自己保持优先权。每个人都想获得最大量,并且他们每步都是最优选择。

题解:正难则反。解法一: 令dp[i]表示分配到第i个物品,此时拥有优先权的人的最大量,由于我们是反向求得,则dp[i+1]已求得,则当前优先权的人有两种选择:

(1)这块披萨给自己则dp[i] = sigma: a(i+1,n) - dp[i+1] + a[i] (因为优先权在第i+1回合互换,所以第i回合等于: 总量(i~n) - 互换人的量(dp[i+1]) + a[i] );

(2)这块披萨给别人则dp[i] = dp[i+1],因为i+1回合自己仍是优先权的。

#include <bits/stdc++.h>using namespace std;int dp[55], val[55], sum[55];int main(){    int n;    scanf("%d",&n);    for(int i = 1;i <= n;i ++) scanf("%d",&val[i]);    for(int i = n;i >= 1;i --) {        sum[i] = sum[i + 1] + val[i];        dp[i] = max(dp[i + 1], sum[i + 1] - dp[i + 1] + val[i]); //    }    printf("%d %d\n",sum[1] - dp[1], dp[1]);    return 0;}

解法2:

和解法一类似,对于每一回合,dp[i]表示第i回合,有优先权的人多获得或者少获得的分数。

则dp[i] = max(a[i] - dp[i + 1], dp[i + 1] - a[i]); (dp[i] >= 0)

选这个数则为获得a[i]的分数减去另一个人比他多的分数即dp[i+1];

不选这个则为dp[i+1] - a[i](给别人则自己少了a[i]);

最后由于A+B总分为sum,B比A多了dp[0],所以B = (sum + dp[0]) / 2;

/*#include <bits/stdc++.h>using namespace std;int dp[55], val[55], sum[55];int main(){    int n;    scanf("%d",&n);    for(int i = 1;i <= n;i ++) scanf("%d",&val[i]);    for(int i = n;i >= 1;i --) {        sum[i] = sum[i + 1] + val[i];        dp[i] = max(dp[i + 1], sum[i + 1] - dp[i + 1] + val[i]); //    }    printf("%d %d\n",sum[1] - dp[1], dp[1]);    return 0;}*/#include <bits/stdc++.h>using namespace std;int main(){    int n;    cin >> n;    vector<int>a(n);    for(int i = 0;i < n;i ++) cin >> a[i];    int sum = accumulate(begin(a), end(a), 0);    vector<int>dp(n+1);    dp[n+1] = 0;    for(int i = n - 1;i >= 0;i --) {        dp[i] = max(dp[i + 1] - a[i], a[i] - dp[i + 1]);    }    cout << (sum - dp[0]) / 2 << " " << (sum + dp[0]) / 2 << endl;    return 0;}