USACO/game1 3.3.5 博弈

来源:互联网 发布:源码商城开发公司 编辑:程序博客网 时间:2024/06/03 17:59

这是一个博弈的问题,第一次做这种题,看了题解的。

最后思想什么的都在代码里的。

#include <stdio.h>#include <stdlib.h>/*dp[i][j]=sum[i][j]-min(dp[i][j-1],dp[i+1][j]);这个原理就是假设先假设取第一个,然后第二个人取的话最大就是dp[i][j-1];假设先取的是最后一个最大就是dp[i+1][j];然后取两者最小的,就是第一个的最优*/int min(int a,int b){    if(a>b) return b;    return a;}int main(){    FILE *fin=fopen("game1.in","r");    FILE *fout=fopen("game1.out","w");    int n;    int ars[110]={0};    int sum[110][110]={0};    int first[110]={0};    int dp[110][110]={0};             //dp[i][j]表示从第i到j个数先取能得到的最大数之和    int i ,j,f;    fscanf(fin,"%d",&n);    for(i=1;i<=n;i++)    {        fscanf(fin,"%d",&ars[i]);        first[i]=first[i-1]+ars[i];        dp[i][i]=ars[i];    }    for(i=1;i<=n;i++)    {        for(j=i;j<=n;j++)        {            sum[i][j]=first[j]-first[i-1];        }    }    for(f=1;f<=n;f++)                               //这个我感觉是有点麻烦的,画个递归树    {                                               //然后就知道先求的就是两者的间隔的       for(j=1;j<n;j++)        {            if(f+j<=n)            {                dp[j][j+f]=sum[j][j+f]-min(dp[j][j+f-1],dp[j+1][j+f]);            }        }    }    fprintf(fout,"%d %d\n",dp[1][n],sum[1][n]-dp[1][n]);    return 0;}


原创粉丝点击