zoukankan      html  css  js  c++  java
  • 洛谷 P1430 序列取数

    题面

        假期真的炒鸡忙www,练练车打打球看看书一天就没了(当然还有LOL & 颓废闲聊时间)。

        而且大学在P大必然是打不上ACM之类的吧,只能好好学习了w(亚历山大)

        所以OI真的只能是兴趣了罢,偶尔有时间搞搞,从简单题开始恢复一下就算是当初也很菜的实力w

        好,闲话不多说。

        这道题貌似在LRJ的蓝书里出现过,先手得分max等价于 (先手得分-后手的)max,因为两者和为定值。

        这样就可以得到一个 O(n^3) 的dp,然后我们把从前取和从后取分别前缀or后缀 优化一下(具体见代码注释),就可以做到 O(n^2) 啦!

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N=1005;
    
    int dp,w,f[N][N],g[N][N],a[N],n,T;
    
    /*  
        dp[i][j] means the MAX delta between the first and the second.
        
        f[i][j] = min{w[i][j]+dp[i][j],w[i+1][j]+dp[i+1][j],...,w[j][j]+dp[j][j]}
    	g[i][j] is similar... (reverse)
    	
    	And there w[i][j] means the sum of a[k](k from i to j)
    	
    	Initially, dp[i][i] = a[i], f[i][i]=g[i][i]= 2*a[i].
    	Except the initial, dp[i][j] = w[i][j] - min(f[i+1][j],g[i][j-1],0) 
    	
    	
    	Finally the ans is (dp[1][n]+w[1][n])/2.
    */
    
    inline void solve(){
    	for(int i=1;i<=n;i++) f[i][i]=g[i][i]=2*a[i],a[i]+=a[i-1];
    	
    	for(int l=1;l<n;l++)
    	    for(int i=1,j=i+l;j<=n;j++,i++){
    	    	w=a[j]-a[i-1];
    	    	dp=w-min(0,min(f[i+1][j],g[i][j-1]));
    	    	f[i][j]=min(f[i+1][j],w+dp);
    	    	g[i][j]=min(g[i][j-1],w+dp);
    		}
    	
    	printf("%d
    ",dp+a[n]>>1);
    }
    
    int main(){
    	scanf("%d",&T);
    	while(T--){
    		scanf("%d",&n);
    		for(int i=1;i<=n;i++) scanf("%d",a+i);
    		
    		if(n==1) printf("%d
    ",a[1]); else solve();
    	}
    	
    	return 0;
    }
    

      

  • 相关阅读:
    Python学习(十六)内置函数,递归
    Python学习(十五)json串使用,不固定参数,关键词参数
    Python学习(十四)常量,局部变量,全局变量
    python学习(十三)函数
    python学习(十二)模块
    Python学习(十一)文件指针,文件操作练习,修改文件
    mongodb聚合
    mongodb
    软件测试需要学习哪些课程
    Jmeter的使用和监控分析
  • 原文地址:https://www.cnblogs.com/JYYHH/p/11256538.html
Copyright © 2011-2022 走看看