[绍兴集训2019]test2-15 (noip模拟题/动态规划专场)

吐槽

一场简单的dp专场noip模拟题,可能是想给我这样的辣鸡选手一点自信,可是我没有领情。
正常选手得分:100+100+100
我的期望得分:100+100+30
我的实际得分:0+50+0
今年上半年我将继续扮演爆零士的角色,t1,t3双爆0。
t1对拍的时候输出了整个数组忘了注释掉,全场唯一一个t1爆零。
t2按n预处理2的幂,n=20的点幂不够挂了。没有前缀和优化后面T了。
t3打了暴力然后暴力写挂。

然后成功让大家看清了我弱智选手的本质。

题解

T1 分裂

发现价值和只跟分裂结果有关而和过程无关,最终价值和就是最后分裂出的所有小块两两相乘求和。
贪心可知分得尽量平均价值最大。
我是暴力dp求最大的分法, f [ i ] [ j ] f[i][j] f[i][j]表示i分成j份的最大价值,转移可用斜率优化,复杂度O(n^2).

//Achen
#include<bits/stdc++.h>
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
#define Formylove return 0
const int N=1007;
typedef long long LL;
typedef double db;
using namespace std;
int S,M,s[N][N],que[N],ql,qr;
LL f[N],g[N];

template<typename T> void read(T &x) {
   
	char ch=getchar(); T f=1; x=0;
	while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
	if(ch=='-') f=-1,ch=getchar();
	for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}
LL getx(int i) {
    return -i; }
LL gety(int i) {
    return f[i]-i*i; }
LL cross(LL ax,LL ay,LL bx,LL by) {
    return ax*by-ay*bx; }
LL get(int i,int j) {
    return f[i]+i*(j-i); }

int main() {
   
    freopen("split.in","r",stdin);
    freopen("split.out","w",stdout);
  	read(S); read(M);
  	For(i,1,S-1) {
   
  		ql=1; qr=0;
		For(x,1,S) {
   
			while(ql<qr&&get(que[ql],x)<=get(que[ql+1],x)) ql++;
			g[x]=get(que[ql],x);
			while(ql<qr&&cross(getx(x)-getx(que[qr-1]),gety(x)-gety(que[qr-1]),getx(que[qr])-getx(que[qr-1]),gety(que[qr])-gety(que[qr-1]))>=0) qr--;
			que[++qr]=x;
		}
		For(x,1,S) f[x]=g[x];
		//For(x,1,S) printf("%d ",f[x]);
		if(f[S]>=M) {
   
			printf("%d\n",i);
			Formylove;
		}
	}
	puts("-1");
	Formylove;
}

T2 异或计数

b i &lt; = a i b_i&lt;=a_i bi<=ai,<

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值