zoukankan      html  css  js  c++  java
  • USACO3.3.5A Game

    A Game
    IOI'96 - Day 1

    Consider the following two-player game played with a sequence of N positive integers (2 <= N <= 100) laid onto a game board. Player 1 starts the game. The players move alternately by selecting a number from either the left or the right end of the sequence. That number is then deleted from the board, and its value is added to the score of the player who selected it. A player wins if his sum is greater than his opponents.

    Write a program that implements the optimal strategy. The optimal strategy yields maximum points when playing against the "best possible" opponent. Your program must further implement an optimal strategy for player 2.

    PROGRAM NAME: game1

    INPUT FORMAT

    Line 1: N, the size of the board
    Line 2-etc: N integers in the range (1..200) that are the contents of the game board, from left to right

    SAMPLE INPUT (file game1.in)

    6
    4 7 2 9
    5 2
    

    OUTPUT FORMAT

    Two space-separated integers on a line: the score of Player 1 followed by the score of Player 2.

    SAMPLE OUTPUT (file game1.out)

    18 11
    题解:这个博弈问题可以用动态规划来解决。设sum[i]为序列s[1]...s[i]的和,f[i][j]表示先手玩家在序列i..j中获得的最大值。那么f[i][j]=sum[j]-sum[i-1]-min(f[i+1][j],f[i][j-1]),这个方程表示的是,如果先手玩家选取左边的元素s[i]或者右边的元素s[j],那么后手玩家肯定也会用最优策略选取f[i+1][j]或者f[i][j-1],我们只要使得后手玩家在序列i..j中获得的最大值最小即可。循环的时候注意i是从n递减的,因为我们要保证由飞f[i+1][j]和f[i][j-1]这两个子问题得出f[i][j]。(第一次提交的时候i是从1递增到n,果断WA了。。。以后记得认真考虑循环控制)。
    View Code
     1 /*
     2 ID:spcjv51
     3 PROG:game1
     4 LANG:C
     5 */
     6 #include<stdio.h>
     7 #include<string.h>
     8 #define MAXSN 100
     9 long min(long a,long b)
    10 {
    11     return a<b?a:b;
    12 }
    13 int main(void)
    14 {
    15     freopen("game1.in","r",stdin);
    16     freopen("game1.out","w",stdout);
    17     long f[MAXSN+5][MAXSN+5],sum[MAXSN+5];
    18     int s[MAXSN+5];
    19     int i,j,n;
    20     scanf("%d",&n);
    21     sum[0]=0;
    22     for(i=1; i<=n; i++)
    23     {
    24         scanf("%d",&s[i]);
    25         sum[i]=sum[i-1]+s[i];
    26         f[i][i]=s[i];
    27     }
    28     for(i=n; i>=1; i--)
    29         for(j=i+1; j<=n; j++)
    30             f[i][j]=sum[j]-sum[i-1]-min(f[i+1][j],f[i][j-1]);
    31     printf("%ld %ld\n",f[1][n],sum[n]-f[1][n]);
    32     return 0;
    33 }


  • 相关阅读:
    KMP算法中next数组的构建
    vijos 1243 生产产品
    codeforces 557E Ann and Half-Palindrome
    codeforces 557D Vitaly and Cycle
    vijos 1054 牛场围栏 【想法题】
    oracle数据库基本操作
    一位90后程序员的自述:如何从年薪3w到30w
    Oracle 树操作(select…start with…connect by…prior)
    oracle中的条件语句
    重置按钮_reset
  • 原文地址:https://www.cnblogs.com/zjbztianya/p/2938637.html
Copyright © 2011-2022 走看看