POJ-2479

DP基础题

属于DP求最大字串和的变形

 

d1[x]代表在a[0,x]中,包含a[x](即a[x',x])的最优解——其实就是标准DP求最大字串是用的数组

c1[x]代表在a[0,x]中,可以不包含a[x]的最优解。

d2, c2是反向的,道理相同。

 

转移方程

  d1[i] = (d1[i-1] < 0) ? (a[i]) : (d1[i-1] + a[i]);

  c1[i] = maxx(c1[i-1], d1[i]);

  d2, c2类似

 

最终通过c1, c2计算出结果即可

#include<cstdio>

#define MAXN 50010
#define maxx(a,b) ((a)>(b))?(a):(b)

int a[MAXN];
int d1[MAXN], c1[MAXN];
int d2[MAXN], c2[MAXN];

int main(void)
{
  //std::ios::sync_with_stdio(false);
  int T, n;
  int ans;
  scanf("%d", &T);//cin>>T;
  for(int t = 0; t < T; t++){
    scanf("%d", &n);//cin>>n;
    for(int i = 0; i < n; ++i) scanf("%d", &a[i]);//cin>>a[i];
    d1[0] = a[0];
    c1[0] = a[0];
    for(int i = 1; i < n; ++i){
      d1[i] = (d1[i-1] < 0) ? (a[i]) : (d1[i-1] + a[i]);
      c1[i] = maxx(c1[i-1], d1[i]);
    }
    d2[n-1] = a[n-1];
    c2[n-1] = a[n-1];
    for(int i = n-2; i >= 0 ; --i){
      d2[i] = (d2[i+1] < 0) ? (a[i]) : (d2[i+1] + a[i]);
      c2[i] = maxx(c2[i+1], d2[i]);
    }
    ans = c1[0] + c2[1];
    for(int i = 2; i < n; ++i)
      ans = maxx(ans, c1[i-1]+c2[i]);
    printf("%d\n", ans);//cout<<ans<<endl;
    /*for(int i = 0; i < n; ++i)
      printf("c1[%d] = %d\n", i, c1[i]);
    for(int i = 0; i < n; ++i)
      printf("c2[%d] = %d\n", i, c2[i]);*/
  }
  return 0;
}

 这一题虽然很弱,但收获不小。

1.从今以后,尽量避免iostream这个坑,TLE非常令人感动,即使加上了看不懂的std::ios::sync_with_stdio(false)也无济于事。

2.通过本题,学会了白书上的批处理标程,虽说最后没其什么作用,但好歹是会了。

3.终于不TLE了居然还WA,一开始我是崩溃的,最终发现一开始我就猜到的全是负的那种数据真的是存在的,但是我明明考虑到了啊,好吧,一小时以后我终于发现,我的思路没有问题,只是中间一个c2打成c1了,看来这个起名的方式以后得好好考虑考虑。

posted on 2015-08-20 00:08  AlanXue  阅读(390)  评论(0编辑  收藏  举报

导航