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

    题目描述

    给定一个长为n的整数序列(n<=1000),由A和B轮流取数(A先取)。每个人可从序列的左端或右端取若干个数(至少一个),但不能两端都取。所有数都被取走后,两人分别统计所取数的和作为各自的得分。假设A和B都足够聪明,都使自己得分尽量高,求A的最终得分。

    输入输出格式

    输入格式:

    第一行,一个正整数T,表示有T组数据。(T<=100)

    接着T行,每行第一个数为n,接着n个整数表示给定的序列.

    输出格式:

    输出T行,每行一个整数,表示A的得分。

    题解:

    这题刚看的时候觉得还挺简单啊,不就是一个DP么,被刷成了这种难度,是什么鬼,然后看到了n<=1000,嗯,有点难度了,n^3做法过不了。。。但是稍微加点剪枝什么的几个亿开了O2不还是随便过,然后发现T<=100.。。。出题人有病么,与其把时限开到3s,还不如少几组数据。。。。于是发现N^3明显不可做,开始考虑如何优化掉一个n。考虑原来的DP方程,就是f[i][j]=s[i]-s[j-1]-min(d[i-1][j],[i-2][j],d[i-3][j]....d[i][j-2],d[i][j-1],0)。

    发现我们可以记录下来当前左端和右端取的最优方法,即

    L[i][j]=min(f[i][j],L[i+1][j]);
    R[i][j]=min(f[i][j],R[i][j-1]);

    然后使f[i][j]=s[i]-s[j-1]-min(0,L[i+1][j],R[i][j-1])就可以了。

    因为这三个都可以通过O1互相递推出来,于是就省去了一个N

    然后发现数据明显不对头,明明5个亿在开O(2)的情况下竟跑了1700+ms。。。这题数据有毒,,,。

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include <iostream>
    #include <cstdlib>
    #include <cmath>
    #include <string>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <queue>
    #include <set>
    #include <map>
    #define re register
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    #define MAXN 1e5+1
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    #define ms(arr) memset(arr, 0, sizeof(arr))
    const int inf = 0x3f3f3f3f;
    int T,n,maxx,ans,f[1001][1001],L[1001][1001],R[1001][1001],a[200001],s[2001];
    inline int read()
    {
        int x=0,c=1;
        char ch=' ';
        while((ch>'9'||ch<'0')&&ch!='-')ch=getchar();
        while(ch=='-') c*=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-'0',ch=getchar();
        return x*c;
    }
    int main() 
    {
        //freopen("date.in","r",stdin);
        T=read();
        while(T--){
            n=read();
            for(re int i=1;i<=n;i++){
                a[i]=read();
                s[i]=s[i-1]+a[i];
                f[i][i]=L[i][i]=R[i][i]=a[i];
            }
            for(re int l=1;l<=n;l++){
                for(re int i=1;i<=n-l;i++){
                    int j=i+l,maxx=0;
                    maxx=min(maxx,min(L[i+1][j],R[i][j-1]));
                    f[i][j]=s[j]-s[i-1]-maxx;
                    L[i][j]=min(f[i][j],L[i+1][j]);
                    R[i][j]=min(f[i][j],R[i][j-1]);
                }
            }
            printf("%d
    ",f[1][n]);
        }
        return 0;
    }
    
  • 相关阅读:
    在Xampp中添加memache扩展
    使用PHP中的curl发送请求
    php开启openssl扩展
    chisel初见2
    chisel初见
    数字IC设计之DC(二):DC设置、库和对象
    数字IC设计之DC(一):DC简介
    IC基础(八):数字电路设计中常用的算法
    IC基础(七):FPGA为什么与ASIC频率差异巨大?
    IC基础(六):时序分析过程需要的相关计算以及处理方法
  • 原文地址:https://www.cnblogs.com/victorique/p/8830679.html
Copyright © 2011-2022 走看看