• UVA10891 Game of Sum


     

    题意:给出N个数,然后有两个小伙伴在玩游戏,每次可以从这一排数字的两侧中选择一侧开始取连续的数,必须取一个,也可以取完。这两个小伙伴都会采用最优的策略来取数,问第一个小伙伴取数的和与第2个小伙伴取数的和的差值。

    记忆化搜索。

    因为两个人分数总和是一定的,所以一个人的小了,另一个就一定大。

    因为双方都是最优策略,所以我们对每一次转移都用最优的方式。

    用f[l][r]表示先手在先取l~r这段区间的最优策略的得分。

    用tot[l][r]-f[i][r](l<i<=r)和tot[l][r]-f[l][i](l<=i<r)来更新f[l][r]。

    //Serene
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    const int maxn=100+10,INF=0x3f3f3f3f;
    int n,sum[maxn],f[maxn][maxn];
    
    int aa,ff;char cc;
    int read() {
    	aa=0;cc=getchar();ff=1;
    	while(cc<'0'||cc>'9') {
    		if(cc=='-') ff=-1;
    		cc=getchar();
    	}
    	while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
    	return aa*ff;
    }
    
    int s(int l,int r) {
    	if(l==r) return sum[r]-sum[l-1];
    	if(f[l][r]!=INF) return f[l][r];
    	int rs=0;
    	for(int i=l+1;i<=r;++i) rs=min(rs,s(i,r));
    	for(int i=l;i<r;++i) rs=min(rs,s(l,i));
    	return f[l][r]=sum[r]-sum[l-1]-rs;
    }
    
    int main() {
    	n=read();
    	while(n) {
    		memset(sum,0,sizeof(sum));
    		memset(f,0x3f3f3f3f,sizeof(f));
    		for(int i=1;i<=n;++i) sum[i]=sum[i-1]+read();
    		printf("%d
    ",2*s(1,n)-sum[n]);
    		n=read();
    	}
    	return 0;
    }
    

      

    弱者就是会被欺负呀
  • 相关阅读:
    人月神话阅读笔记之一
    第一阶段冲刺站立会议报告——9
    第一阶段冲刺站立会议报告——8
    第一阶段冲刺站立会议报告——7
    第一阶段冲刺站立会议报告——6
    第一阶段冲刺站立会议报告——5
    第二阶段冲刺第一天
    寻找水王2
    构建之法阅读笔记05
    第十二周学习进度条
  • 原文地址:https://www.cnblogs.com/Serene-shixinyi/p/7604184.html
Copyright © 2020-2023  润新知