zoukankan      html  css  js  c++  java
  • ABC 162 F Select Half dp 贪心

    LINK:Select Half

    考试的时候调了一个小时给调自闭了 原来是dp的姿势不太对。

    首先 容易发现 奇数最多空2个位置 偶数最多空1一个位置 然后 设f[i][j][k]表示第i个数选了没有j 且当前用了k个空位的最大值。

    然后把自己给dp迷了 最后发现选的数量无法固定所以 这个dp崩了。

    考虑贪心不难发现偶数最多有两个空位连在一起 这个可以暴力枚举 奇偶性直接拿。

    奇数 可以三个空位连在一起 或者 有4个不相邻的空位 存在。

    前者可以暴力枚举 后者需要一些诡异的操作 最后发现前后缀和出现了点边界问题 导致GG.

    最终还是选择dp.

    说是姿势不对的原因是 j这维没啥用 直接利用i-2转移即可 那么有状态 f[i][j]表示前i个数当前用了j个空位的最大值。

    一些状态转移不再赘述。

    最后点一下细节 可以发现但是偶数时f[n][0],f[n][1],f[n-1][0]都可能作为答案。

    为奇数的时候 可以发现f[n][2],f[n][1],f[n-1][1],f[n-1][0],f[n-2][0]都可以作为答案。

    可以发现上述状态都是选择了n/2个数字的。

    const ll MAXN=200005;
    ll n;
    ll a[MAXN];
    ll f[MAXN][3];//f[i][j]前表示前i个数用掉j个空隙的最大值.
    signed main()
    {
    	freopen("1.in","r",stdin);
    	get(n);
    	rep(1,n,i)get(a[i]);
    	memset(f,0xcf,sizeof(f));
    	f[0][0]=0;f[1][0]=a[1];
    	rep(2,n,i)
    	{
    		f[i][0]=f[i-2][0]+a[i];
    		if(i>=3)f[i][1]=max(f[i-3][0]+a[i],f[i-2][1]+a[i]);
    		if(i>=4)f[i][2]=max(f[i-4][0]+a[i],max(f[i-3][1]+a[i],f[i-2][2]+a[i]));
    	}
    	if(n&1)putl(max(max(f[n][1],f[n][2]),max(f[n-2][0],max(f[n-1][0],f[n-1][1]))));
    	else putl(max(f[n][1],max(f[n][0],f[n-1][0])));
    	return 0;
    }
    

    其实真的是要贪心的话虽然很繁杂但是也是可以做的。

  • 相关阅读:
    手写堆排序和归并排序
    海量数据处理
    HDU 1532 --&&-- POJ1273 dinic 算法
    POJ 3159 最短路 SPFA
    POJ 1459 网络流 EK算法
    8.14比赛j题 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=87813#overview
    单链表---邻接表
    poj 1273 ---&&--- hdu 1532 最大流模板
    HDU 2603 二分匹配
    UVA 796 连通图求桥
  • 原文地址:https://www.cnblogs.com/chdy/p/12693229.html
Copyright © 2011-2022 走看看