博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【BZOJ】3502 PA2012 Tanie linie
阅读量:6232 次
发布时间:2019-06-21

本文共 2390 字,大约阅读时间需要 7 分钟。

【算法】贪心,一般DP

【题解】

---

胡策k≤10的环状DP做法:

1.钦定法:先确定第一位(可能和第n位)的状态,然后后面正常做DP,显然正确答案是一定会被记录的,因为从整体上看不会有影响。

2.环的特性:取的段和不取的段数量相等,位置互补。所以1和n的连接处都选或都不选都会有不被包括的情况,一选一不选就和链一样了。

---

正解贪心:

因为相邻的正数或相邻的负数肯定是要选一起选,所以点缩成正负正负…的数列形式,那么考虑先选择全部正的。

如果选择的段数过多,考虑删除则有两种选择:舍弃一个正数(相当于舍弃一个正数和两个负数,把这三个数视为一个负数),选择一个负数(相当于选择一个负数和两个正数,把这三个数视为一个正数)。

那么显然这两种行为是等价的:都是合并相邻的三个数字,可以视为对绝对值最小的数字操作最优,然后过程中用堆动态维护即可。

非环的情况特殊处理:不可能选择头尾的负数,因为没办法合并两个正数,过程中需要判断这个,而且这个头尾还会变化。

 

对拍还是查找错误相当重要的方式!考试一定要写暴力拍!

据说可以开头特判一些东西跳掉没用的数据——数据是死的,人是活的,出题人是懒的。

#include
#include
#include
#include
using namespace std;const int maxn=1000010;long long a[maxn],n,m,k,b[maxn],pre[maxn],suc[maxn];bool f[maxn];struct cyc{ long long num,ord; bool p; bool operator <(const cyc &a) const { return num>a.num; }}qp;priority_queue
q;int main(){ // freopen("input","r",stdin); scanf("%lld%lld",&n,&k); bool now=0;long long tot,m=0; long long ans=0; scanf("%lld",&a[1]); b[(tot=1)]=a[1];now=a[1]>0; for(int i=2;i<=n;i++) { scanf("%lld",&a[i]); if(a[i]>0&&!now) { now=1; b[++tot]=a[i]; } else if(a[i]<=0&&now) { now=0; b[++tot]=a[i]; } else b[tot]+=a[i]; }// if((b[tot]>0)==(b[1]>0)&&tot!=1){b[1]+=b[tot];tot--;}//操作顺序 for(int i=1;i<=tot;i++) { pre[i]=i-1;suc[i]=i+1; if(b[i]>0){ans+=b[i];m++;} q.push((cyc){(b[i]>0?b[i]:-b[i]),i,b[i]>0}); }// pre[1]=tot;suc[tot]=1; suc[tot]=0; long long en=tot,be=1; for(int i=m;i>k;i--) { while(f[q.top().ord]||((q.top().ord==be||q.top().ord==en)&&!q.top().p))q.pop(); qp=q.top();q.pop(); long long sum=0;long long A=pre[qp.ord],B=suc[qp.ord]; if(qp.p)sum=qp.num+b[A]+b[B]; else sum=b[A]+b[B]-qp.num; ans-=qp.num; if(suc[pre[A]])suc[pre[A]]=qp.ord;pre[qp.ord]=pre[A]; if(pre[suc[B]])pre[suc[B]]=qp.ord;suc[qp.ord]=suc[B]; f[A]=f[B]=1;b[qp.ord]=sum; //printf("ord=%lld num=%lld sum=%lld\n",qp.ord,qp.num,sum); if(B==en)en=qp.ord; if(A==be)be=qp.ord; q.push((cyc){(sum>0?sum:-sum),qp.ord,sum>0}); } printf("%lld",ans);//开long long return 0;}
View Code

 

转载于:https://www.cnblogs.com/onioncyc/p/7086943.html

你可能感兴趣的文章
bash腳本編程之三 条件判断及算数运算
查看>>
php cookie
查看>>
linux下redis安装
查看>>
弃 Java 而使用 Kotlin 的你后悔了吗?| kotlin将会是最好的开发语言
查看>>
JavaScript 数据类型
查看>>
量子通信和大数据最有市场突破前景
查看>>
对‘初学者应该选择哪种编程语言’的回答——计算机达人成长之路(38)
查看>>
如何申请开通微信多客服功能
查看>>
Sr_C++_Engineer_(LBS_Engine@Global Map Dept.)
查看>>
非监督学习算法:异常检测
查看>>
jquery的checkbox,radio,select等方法总结
查看>>
Linux coredump
查看>>
Ubuntu 10.04安装水晶(Mercury)无线网卡驱动
查看>>
我的友情链接
查看>>
nginx在reload时候报错invalid PID number
查看>>
ElasticSearch 2 (32) - 信息聚合系列之范围限定
查看>>
VS2010远程调试C#程序
查看>>
[MicroPython]TurniBit开发板DIY自动窗帘模拟系统
查看>>
Python3.4 12306 2015年3月验证码识别
查看>>
从Handler.post(Runnable r)再一次梳理Android的消息机制(以及handler的内存泄露)
查看>>