文章目录
吐槽
一场简单的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 < = a i b_i<=a_i bi<=ai,<