LINK:国王饮水记

看起来很不可做的样子.

但实际上还是需要先考虑贪心.

当k==1的时候 只有一次操作机会。显然可以把那些比第一个位置小的都给扔掉.

然后可以得知剩下序列中的最大值一定会被选择.

考虑是否选出其他数字 容易想到如果选择了必然要比拿到最大的之后的平均数要大.

这样贪心下去即可.

考虑当k不等于1的时候.

设\(f_i\)表示第i次使用过后的最大值.显然有\(f_i>f_{i-1}\)

那么由此我们得到某个点至多被选择一次 再选择没有任何收益.

所以k可以对n取min.

此时观察数据范围 可以暴力状压 再对k==1单独处理 期望得分40.

然后我们思考如果先选最大的刚开始可能增幅最大 可是反过来削弱了一些原本可以有贡献的点.

先让小的先增幅 大的也再增幅这无疑是更优的.

那么我们考虑从小到大选 然后我们可以发现每次选择应该是连续的一段.

如果不连续 那么我们可以发现两端中间的元素 会被左边元素削弱 理由同上还是存在先选大的再选小的了.

所以我们可以设一个状态了 \(f_{i,j}\)表示到第i个位置选了j次的最大值.

显然有 \(f_{i,j}=(f_{k,j-1}+S_i-S_k)/(i-k+1)\)

这样复杂度为 \(n^2\cdot k\cdot p\) 期望得分60.

不过这个需要使用题目中给出的高精浮点型 观察一下调用即可.

code
//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<ctime>
#include<cctype>
#include<queue>
#include<deque>
#include<stack>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<queue>
#include<deque>
#include<stack>
#include<vector>
#include<algorithm>
#include<utility>
#include<bitset>
#include<set>
#include<map>
#define ll long long
#define db double
#define INF 1000000000000000000ll
#define inf 100000000000000000ll
#define ldb long double
#define pb push_back
#define put_(x) printf("%d ",x);
#define get(x) x=read()
#define gt(x) scanf("%d",&x)
#define gi(x) scanf("%lf",&x)
#define put(x) printf("%d\n",x)
#define putl(x) printf("%lld\n",x)
#define rep(p,n,i) for(RE int i=p;i<=n;++i)
#define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define fep(n,p,i) for(RE int i=n;i>=p;--i)
#define vep(p,n,i) for(RE int i=p;i<n;++i)
#define pii pair<int,int>
#define mk make_pair
#define RE register
#define P 1000000007ll
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define uint unsigned long long
#define ui unsigned
#define EPS 1e-10
#define sq sqrt
#define S second
#define F first
#define mod 1000000007
#define r(x) t[x].r
#define l(x) t[x].l
#define mx1(x) t[x].mx1
#define mx2(x) t[x].mx2
#define max(x,y) ((x)<(y)?y:x)
using namespace std;
char *fs,*ft,buf[1<<15];
inline char gc()
{
return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
}
inline int read()
{
RE int x=0,f=1;RE char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=gc();}
return x*f;
}
const int MAXN=1010;
int n,k,p,cnt,W;
int a[MAXN];
db f[MAXN][MAXN];
int main()
{
//freopen("1.in","r",stdin);
get(n);get(k);get(p);get(W);
rep(2,n,i)
{
int get(x);
if(x>W)a[++cnt]=x;
}
n=cnt;
if(p<=5)
{
sort(a+1,a+1+n);
rep(1,n,i)a[i]+=a[i-1];
k=min(k,n);
rep(0,n,j)f[j][0]=W;
rep(0,n,i)
{
rep(1,k,j)
{
f[i][j]=f[i][j-1];
rep(0,i-1,l)
{
f[i][j]=max(f[i][j],(f[l][j-1]+a[i]-a[l])/(i-l+1));
}
}
}
printf("%.8lf",f[n][k]);
return 0;
}
return 0;
}

感觉这种式子会存在决策单调性 先枚举j再枚举i打表 发现决策确实具有单调性.

证明可以自己观察式子吧 我没仔细分析 但是感觉存在单调性...

分治法\(n\cdot k\cdot p\cdot logn\)

一个以前从没注意过的东西 这个式子可以斜率优化.

转移式的形式可以看成两点的斜率大小 这个东西也可以进行斜率优化.

维护下凸壳和当前点横纵左边都递增维护队列列两点斜率的大小关系即可.

复杂度\(n\cdot k\cdot p\)期望得分\(80\)

接下来由两个trick可以优化.

一个是 dp的时候可以先使用double型数组做 然后最后再使用高精浮点获得决策来做.

这样前者是\(nk\)后者\(k\cdot p\)期望得分100.

我想正确性应该没什么问题 恰好做到了决策之间的细微差距再十几位小数的时候就被分辨.

第二个是 当k==n的时候 显然每次两个单独合并是最优的.

当k<n的时候必须有一些点是一起合并的 且每次合并的区间大小递减.

可以证明在当前数据范围最多有14次是整段合并 后面都是单个合并。

不会证明.不过第一个方法已经可以通过 加上这个可以更快.

(700多行代码警告!

\(14\cdot n+k\cdot p\)

code
// This is an empty program with decimal lib

#include <cstdlib>
#include <cstring>
#include <string> // ---------- decimal lib start ---------- const int PREC = 3000; class Decimal {
public:
Decimal();
Decimal(const std::string &s);
Decimal(const char *s);
Decimal(int x);
Decimal(long long x);
Decimal(double x); bool is_zero() const; // p (p > 0) is the number of digits after the decimal point
std::string to_string(int p) const;
double to_double() const; friend Decimal operator + (const Decimal &a, const Decimal &b);
friend Decimal operator + (const Decimal &a, int x);
friend Decimal operator + (int x, const Decimal &a);
friend Decimal operator + (const Decimal &a, long long x);
friend Decimal operator + (long long x, const Decimal &a);
friend Decimal operator + (const Decimal &a, double x);
friend Decimal operator + (double x, const Decimal &a); friend Decimal operator - (const Decimal &a, const Decimal &b);
friend Decimal operator - (const Decimal &a, int x);
friend Decimal operator - (int x, const Decimal &a);
friend Decimal operator - (const Decimal &a, long long x);
friend Decimal operator - (long long x, const Decimal &a);
friend Decimal operator - (const Decimal &a, double x);
friend Decimal operator - (double x, const Decimal &a); friend Decimal operator * (const Decimal &a, int x);
friend Decimal operator * (int x, const Decimal &a); friend Decimal operator / (const Decimal &a, int x); friend bool operator < (const Decimal &a, const Decimal &b);
friend bool operator > (const Decimal &a, const Decimal &b);
friend bool operator <= (const Decimal &a, const Decimal &b);
friend bool operator >= (const Decimal &a, const Decimal &b);
friend bool operator == (const Decimal &a, const Decimal &b);
friend bool operator != (const Decimal &a, const Decimal &b); Decimal & operator += (int x);
Decimal & operator += (long long x);
Decimal & operator += (double x);
Decimal & operator += (const Decimal &b); Decimal & operator -= (int x);
Decimal & operator -= (long long x);
Decimal & operator -= (double x);
Decimal & operator -= (const Decimal &b); Decimal & operator *= (int x); Decimal & operator /= (int x); friend Decimal operator - (const Decimal &a); // These can't be called
friend Decimal operator * (const Decimal &a, double x);
friend Decimal operator * (double x, const Decimal &a);
friend Decimal operator / (const Decimal &a, double x);
Decimal & operator *= (double x);
Decimal & operator /= (double x); private:
static const int len = PREC / 9 + 1;
static const int mo = 1000000000; static void append_to_string(std::string &s, long long x); bool is_neg;
long long integer;
int data[len]; void init_zero();
void init(const char *s);
}; Decimal::Decimal() {
this->init_zero();
} Decimal::Decimal(const char *s) {
this->init(s);
} Decimal::Decimal(const std::string &s) {
this->init(s.c_str());
} Decimal::Decimal(int x) {
this->init_zero(); if (x < 0) {
is_neg = true;
x = -x;
} integer = x;
} Decimal::Decimal(long long x) {
this->init_zero(); if (x < 0) {
is_neg = true;
x = -x;
} integer = x;
} Decimal::Decimal(double x) {
this->init_zero(); if (x < 0) {
is_neg = true;
x = -x;
} integer = (long long)x;
x -= integer; for (int i = 0; i < len; i++) {
x *= mo;
if (x < 0) x = 0;
data[i] = (int)x;
x -= data[i];
}
} void Decimal::init_zero() {
is_neg = false;
integer = 0;
memset(data, 0, len * sizeof(int));
} bool Decimal::is_zero() const {
if (integer) return false;
for (int i = 0; i < len; i++) {
if (data[i]) return false;
}
return true;
} void Decimal::init(const char *s) {
this->init_zero(); is_neg = false;
integer = 0; // find the first digit or the negative sign
while (*s != 0) {
if (*s == '-') {
is_neg = true;
++s;
break;
} else if (*s >= 48 && *s <= 57) {
break;
}
++s;
} // read the integer part
while (*s >= 48 && *s <= 57) {
integer = integer * 10 + *s - 48;
++s;
} // read the decimal part
if (*s == '.') {
int pos = 0;
int x = mo / 10; ++s;
while (pos < len && *s >= 48 && *s <= 57) {
data[pos] += (*s - 48) * x;
++s;
x /= 10;
if (x == 0) {
++pos;
x = mo / 10;
}
}
}
} void Decimal::append_to_string(std::string &s, long long x) {
if (x == 0) {
s.append(1, 48);
return;
} char _[30];
int cnt = 0;
while (x) {
_[cnt++] = x % 10;
x /= 10;
}
while (cnt--) {
s.append(1, _[cnt] + 48);
}
} std::string Decimal::to_string(int p) const {
std::string ret; if (is_neg && !this->is_zero()) {
ret = "-";
} append_to_string(ret, this->integer); ret.append(1, '.'); for (int i = 0; i < len; i++) {
// append data[i] as "%09d"
int x = mo / 10;
int tmp = data[i];
while (x) {
ret.append(1, 48 + tmp / x);
tmp %= x;
x /= 10;
if (--p == 0) {
break;
}
}
if (p == 0) break;
} if (p > 0) {
ret.append(p, '0');
} return ret;
} double Decimal::to_double() const {
double ret = integer; double k = 1.0;
for (int i = 0; i < len; i++) {
k /= mo;
ret += k * data[i];
} if (is_neg) {
ret = -ret;
} return ret;
} bool operator < (const Decimal &a, const Decimal &b) {
if (a.is_neg != b.is_neg) {
return a.is_neg && (!a.is_zero() || !b.is_zero());
} else if (!a.is_neg) {
// a, b >= 0
if (a.integer != b.integer) {
return a.integer < b.integer;
}
for (int i = 0; i < Decimal::len; i++) {
if (a.data[i] != b.data[i]) {
return a.data[i] < b.data[i];
}
}
return false;
} else {
// a, b <= 0
if (a.integer != b.integer) {
return a.integer > b.integer;
}
for (int i = 0; i < Decimal::len; i++) {
if (a.data[i] != b.data[i]) {
return a.data[i] > b.data[i];
}
}
return false;
}
} bool operator > (const Decimal &a, const Decimal &b) {
if (a.is_neg != b.is_neg) {
return !a.is_neg && (!a.is_zero() || !b.is_zero());
} else if (!a.is_neg) {
// a, b >= 0
if (a.integer != b.integer) {
return a.integer > b.integer;
}
for (int i = 0; i < Decimal::len; i++) {
if (a.data[i] != b.data[i]) {
return a.data[i] > b.data[i];
}
}
return false;
} else {
// a, b <= 0
if (a.integer != b.integer) {
return a.integer < b.integer;
}
for (int i = 0; i < Decimal::len; i++) {
if (a.data[i] != b.data[i]) {
return a.data[i] < b.data[i];
}
}
return false;
}
} bool operator <= (const Decimal &a, const Decimal &b) {
if (a.is_neg != b.is_neg) {
return a.is_neg || (a.is_zero() && b.is_zero());
} else if (!a.is_neg) {
// a, b >= 0
if (a.integer != b.integer) {
return a.integer < b.integer;
}
for (int i = 0; i < Decimal::len; i++) {
if (a.data[i] != b.data[i]) {
return a.data[i] < b.data[i];
}
}
return true;
} else {
// a, b <= 0
if (a.integer != b.integer) {
return a.integer > b.integer;
}
for (int i = 0; i < Decimal::len; i++) {
if (a.data[i] != b.data[i]) {
return a.data[i] > b.data[i];
}
}
return true;
}
} bool operator >= (const Decimal &a, const Decimal &b) {
if (a.is_neg != b.is_neg) {
return !a.is_neg || (a.is_zero() && b.is_zero());
} else if (!a.is_neg) {
// a, b >= 0
if (a.integer != b.integer) {
return a.integer > b.integer;
}
for (int i = 0; i < Decimal::len; i++) {
if (a.data[i] != b.data[i]) {
return a.data[i] > b.data[i];
}
}
return true;
} else {
// a, b <= 0
if (a.integer != b.integer) {
return a.integer < b.integer;
}
for (int i = 0; i < Decimal::len; i++) {
if (a.data[i] != b.data[i]) {
return a.data[i] < b.data[i];
}
}
return true;
}
} bool operator == (const Decimal &a, const Decimal &b) {
if (a.is_zero() && b.is_zero()) return true;
if (a.is_neg != b.is_neg) return false;
if (a.integer != b.integer) return false;
for (int i = 0; i < Decimal::len; i++) {
if (a.data[i] != b.data[i]) return false;
}
return true;
} bool operator != (const Decimal &a, const Decimal &b) {
return !(a == b);
} Decimal & Decimal::operator += (long long x) {
if (!is_neg) {
if (integer + x >= 0) {
integer += x;
} else {
bool last = false;
for (int i = len - 1; i >= 0; i--) {
if (last || data[i]) {
data[i] = mo - data[i] - last;
last = true;
} else {
last = false;
}
}
integer = -x - integer - last;
is_neg = true;
}
} else {
if (integer - x >= 0) {
integer -= x;
} else {
bool last = false;
for (int i = len - 1; i >= 0; i--) {
if (last || data[i]) {
data[i] = mo - data[i] - last;
last = true;
} else {
last = false;
}
}
integer = x - integer - last;
is_neg = false;
}
}
return *this;
} Decimal & Decimal::operator += (int x) {
return *this += (long long)x;
} Decimal & Decimal::operator -= (int x) {
return *this += (long long)-x;
} Decimal & Decimal::operator -= (long long x) {
return *this += -x;
} Decimal & Decimal::operator /= (int x) {
if (x < 0) {
is_neg ^= 1;
x = -x;
} int last = integer % x;
integer /= x; for (int i = 0; i < len; i++) {
long long tmp = 1LL * last * mo + data[i];
data[i] = tmp / x;
last = tmp - 1LL * data[i] * x;
} if (is_neg && integer == 0) {
int i;
for (i = 0; i < len; i++) {
if (data[i] != 0) {
break;
}
}
if (i == len) {
is_neg = false;
}
} return *this;
} Decimal & Decimal::operator *= (int x) {
if (x < 0) {
is_neg ^= 1;
x = -x;
} else if (x == 0) {
init_zero();
return *this;
} int last = 0;
for (int i = len - 1; i >= 0; i--) {
long long tmp = 1LL * data[i] * x + last;
last = tmp / mo;
data[i] = tmp - 1LL * last * mo;
}
integer = integer * x + last; return *this;
} Decimal operator - (const Decimal &a) {
Decimal ret = a;
// -0 = 0
if (!ret.is_neg && ret.integer == 0) {
int i;
for (i = 0; i < Decimal::len; i++) {
if (ret.data[i] != 0) break;
}
if (i < Decimal::len) {
ret.is_neg = true;
}
} else {
ret.is_neg ^= 1;
}
return ret;
} Decimal operator + (const Decimal &a, int x) {
Decimal ret = a;
return ret += x;
} Decimal operator + (int x, const Decimal &a) {
Decimal ret = a;
return ret += x;
} Decimal operator + (const Decimal &a, long long x) {
Decimal ret = a;
return ret += x;
} Decimal operator + (long long x, const Decimal &a) {
Decimal ret = a;
return ret += x;
} Decimal operator - (const Decimal &a, int x) {
Decimal ret = a;
return ret -= x;
} Decimal operator - (int x, const Decimal &a) {
return -(a - x);
} Decimal operator - (const Decimal &a, long long x) {
Decimal ret = a;
return ret -= x;
} Decimal operator - (long long x, const Decimal &a) {
return -(a - x);
} Decimal operator * (const Decimal &a, int x) {
Decimal ret = a;
return ret *= x;
} Decimal operator * (int x, const Decimal &a) {
Decimal ret = a;
return ret *= x;
} Decimal operator / (const Decimal &a, int x) {
Decimal ret = a;
return ret /= x;
} Decimal operator + (const Decimal &a, const Decimal &b) {
if (a.is_neg == b.is_neg) {
Decimal ret = a;
bool last = false;
for (int i = Decimal::len - 1; i >= 0; i--) {
ret.data[i] += b.data[i] + last;
if (ret.data[i] >= Decimal::mo) {
ret.data[i] -= Decimal::mo;
last = true;
} else {
last = false;
}
}
ret.integer += b.integer + last;
return ret;
} else if (!a.is_neg) {
// a - |b|
return a - -b;
} else {
// b - |a|
return b - -a;
}
} Decimal operator - (const Decimal &a, const Decimal &b) {
if (!a.is_neg && !b.is_neg) {
if (a >= b) {
Decimal ret = a;
bool last = false;
for (int i = Decimal::len - 1; i >= 0; i--) {
ret.data[i] -= b.data[i] + last;
if (ret.data[i] < 0) {
ret.data[i] += Decimal::mo;
last = true;
} else {
last = false;
}
}
ret.integer -= b.integer + last;
return ret;
} else {
Decimal ret = b;
bool last = false;
for (int i = Decimal::len - 1; i >= 0; i--) {
ret.data[i] -= a.data[i] + last;
if (ret.data[i] < 0) {
ret.data[i] += Decimal::mo;
last = true;
} else {
last = false;
}
}
ret.integer -= a.integer + last;
ret.is_neg = true;
return ret;
}
} else if (a.is_neg && b.is_neg) {
// a - b = (-b) - (-a)
return -b - -a;
} else if (a.is_neg) {
// -|a| - b
return -(-a + b);
} else {
// a - -|b|
return a + -b;
}
} Decimal operator + (const Decimal &a, double x) {
return a + Decimal(x);
} Decimal operator + (double x, const Decimal &a) {
return Decimal(x) + a;
} Decimal operator - (const Decimal &a, double x) {
return a - Decimal(x);
} Decimal operator - (double x, const Decimal &a) {
return Decimal(x) - a;
} Decimal & Decimal::operator += (double x) {
*this = *this + Decimal(x);
return *this;
} Decimal & Decimal::operator -= (double x) {
*this = *this - Decimal(x);
return *this;
} Decimal & Decimal::operator += (const Decimal &b) {
*this = *this + b;
return *this;
} Decimal & Decimal::operator -= (const Decimal &b) {
*this = *this - b;
return *this;
}
//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<ctime>
#include<cctype>
#include<queue>
#include<deque>
#include<stack>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<queue>
#include<deque>
#include<stack>
#include<vector>
#include<algorithm>
#include<utility>
#include<bitset>
#include<set>
#include<map>
#define ll long long
#define db double
#define INF 1000000000000000000ll
#define inf 100000000000000000ll
#define ldb long double
#define pb push_back
#define put_(x) printf("%d ",x);
#define get(x) x=read()
#define gt(x) scanf("%d",&x)
#define gi(x) scanf("%lf",&x)
#define put(x) printf("%d\n",x)
#define putl(x) printf("%lld\n",x)
#define rep(p,n,i) for(RE int i=p;i<=n;++i)
#define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define fep(n,p,i) for(RE int i=n;i>=p;--i)
#define vep(p,n,i) for(RE int i=p;i<n;++i)
#define pii pair<int,int>
#define mk make_pair
#define RE register
#define P 1000000007ll
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define uint unsigned long long
#define ui unsigned
#define EPS 1e-10
#define sq sqrt
#define S second
#define F first
#define mod 1000000007
#define r(x) t[x].r
#define l(x) t[x].l
#define mx1(x) t[x].mx1
#define mx2(x) t[x].mx2
#define max(x,y) ((x)<(y)?y:x)
using namespace std;
char *fs,*ft,buf[1<<15];
inline char gc()
{
return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
}
inline int read()
{
RE int x=0,f=1;RE char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=gc();}
return x*f;
}
const int MAXN=8010;
int n,k,p,cnt,W;
int a[MAXN],g[MAXN][15];
db f[MAXN][15];
struct wy
{
int id;db x,y;
inline wy operator -(wy a){return (wy){0,x-a.x,y-a.y};}
inline db operator %(wy a){return x*a.y-a.x*y;}
}q[MAXN];
inline Decimal calc(int i,int j)
{
if(!j)return f[i][0];
return (calc(g[i][j],j-1)+a[i]-a[g[i][j]])/(i-g[i][j]+1);
}
int main()
{
//freopen("1.in","r",stdin);
get(n);get(k);get(p);get(W);
rep(2,n,i)
{
int get(x);
if(x>W)a[++cnt]=x;
}
n=cnt;
sort(a+1,a+1+n);
rep(1,n,i)a[i]+=a[i-1];
k=min(k,n);
int lim=min(14,k);
rep(0,n,i)f[i][0]=W;
rep(1,lim,j)
{
int l=1,r=1;
q[r]=(wy){0,-1,a[0]-f[0][j-1]};
rep(1,n,i)
{
wy v=(wy){0,(db)i,(db)a[i]};
while(l<r&&(v-q[l+1])%(v-q[l])<0)++l;
f[i][j]=(a[i]-q[l].y)/(i-q[l].x);
g[i][j]=q[l].id;
v=(wy){i,(db)i-1,(db)a[i]-f[i][j-1]};
while(l<r&&(v-q[r])%(q[r]-q[r-1])>0)--r;
q[++r]=v;
}
}
int ww=n-(k-lim);
int cc;db mx=0;
rep(1,lim,j)if(mx<f[ww][j])mx=f[ww][j],cc=j;
Decimal ans=calc(ww,cc);
rep(ww+1,n,i)ans=(ans+(a[i]-a[i-1]))/2;
cout<<ans.to_string(p<<1)<<endl;
return 0;
}

luogu P1721 [NOI2016]国王饮水记 斜率优化dp 贪心 决策单调性的更多相关文章

  1. uoj233/BZOJ4654/洛谷P1721 [Noi2016]国王饮水记 【dp + 斜率优化】

    题目链接 uoj233 题解 下面不加证明地给出几个性质: 小于\(h[1]\)的城市一定是没用的 任何城市联通包含\(1\)且只和\(1\)联通一次 联通顺序从小到大最优 单个联通比多个一起联通要优 ...

  2. P1721 [NOI2016] 国王饮水记 题解

    蒟蒻的第一篇黑题题解,求过. 题目链接 题意描述 这道题用简洁的话来说,就是: 给你 \(n\) 个数字,你可以让取其中任意若干个数字,每次操作,都会使所有取的数字变为取的数字的平均数,并且你最多只能 ...

  3. [UOJ#223][BZOJ4654][Noi2016]国王饮水记

    [UOJ#223][BZOJ4654][Noi2016]国王饮水记 试题描述 跳蚤国有 n 个城市,伟大的跳蚤国王居住在跳蚤国首都中,即 1 号城市中.跳蚤国最大的问题就是饮水问题,由于首都中居住的跳 ...

  4. BZOJ4654/UOJ223 [Noi2016]国王饮水记

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  5. [Noi2016]国王饮水记

    来自FallDream的博客,未经允许,请勿转载,谢谢. 跳蚤国有 n 个城市,伟大的跳蚤国王居住在跳蚤国首都中,即 1 号城市中.跳蚤国最大的问题就是饮水问题,由于首都中居住的跳蚤实在太多,跳蚤国王 ...

  6. 【Luogu】P3195玩具装箱(斜率优化DP)

    这题还是比较炫的 题目链接 我们设f[i]是已经装了前i个玩具,且第i个玩具是某箱子里装的最后一个东西(废话) 那我们很轻松可以想到一个转移方程 ;i<=n;++i) ;j<i;++j) ...

  7. CF331B Cats Transport[斜率优化dp+贪心]

    luogu翻译 一些山距离起点有距离且不同,m只猫要到不同的山上去玩ti时间,有p个铲屎官人要去把所有猫接走,步行速度为1单位每秒,从1走到N座山不停下,必须在猫玩完后才可以把他带走.可以提前出发.问 ...

  8. BZOJ.1010.[HNOI2008]玩具装箱toy(DP 斜率优化/单调队列 决策单调性)

    题目链接 斜率优化 不说了 网上很多 这的比较详细->Click Here or Here //1700kb 60ms #include<cstdio> #include<cc ...

  9. BZOJ4654 NOI2016国王饮水记(动态规划+三分)

    有很多比较显然的性质.首先每个城市(除1外)至多被连通一次,否则没有意义.其次将城市按水位从大到小排序后,用以连通的城市集合是一段前缀,并且不应存在比1城市还小的.然后如果确定了选取的城市集合,每次选 ...

随机推荐

  1. 基本数据类型--------------------集合set()

    一.作用:集合.list.tuple.dict一样都可以存放多个值,但是集合主要用于:关系运算.去重 # 1.1 关系运算 friends1 = ["zero","kev ...

  2. WPF弹性、惯性效果应用

    WPF弹性.惯性效果.已发布在了一些网站,都是这里写的 代码改编自微软示例代码库 // Copyright © Microsoft Corporation.  All Rights Reserved. ...

  3. .Net Core 2.2升级3.1的避坑指南

    写在前面 微软在更新.Net Core版本的时候,动作往往很大,使得每次更新版本的时候都得小心翼翼,坑实在是太多.往往是悄咪咪的移除了某项功能或者组件,或者不在支持XX方法,这就很花时间去找回需要的东 ...

  4. shell专题(八):read读取控制台输入

    1.基本语法 read(选项)(参数) 选项: -p:指定读取值时的提示符: -t:指定读取值时等待的时间(秒). 参数 变量:指定读取值的变量名 2.案例实操 (1)提示7秒内,读取控制台输入的名称 ...

  5. 爬虫06 /scrapy框架

    爬虫06 /scrapy框架 目录 爬虫06 /scrapy框架 1. scrapy概述/安装 2. 基本使用 1. 创建工程 2. 数据分析 3. 持久化存储 3. 全栈数据的爬取 4. 五大核心组 ...

  6. CSS 三大特性 层叠 继承 优先级

    css三大特性 层叠性: 如果一个属性通过两个相同选择器设置到同一个元素上,相同的属性就会出现冲突,那么这个时候一个属性就会将另一个属性层叠掉,采用的是就近原则 继承性: 子标签会继承父标签的某些样式 ...

  7. 让 axios 支持 finally

    当我们执行一个promise操作时,往往伴随的是要做各种状态的修改(如请求开始时显示loading,结束时隐藏 loading), 这个状态修改,如果没有finally函数,我们需要在then和cat ...

  8. Hangfire实战二——为DashBoard页面添加权限认证

    概述 Hangfire Dashboard为我们提供了可视化的对后台任务进行管理的界面,我们可以直接在这个页面上对定时任务进行删除.立即执行等操作,如下图所示: 默认情况下,这个页面只能在部署Hang ...

  9. Oracle-常见的命令

    --------------输入一下指令,按下快捷键 F8 select * from emp; --------------创建表格 create table 表名( 字段名1 数据类型1, 字段名 ...

  10. 并发编程AQS--------ReentrantLock

    同步框架AbstractQueuedSynchronizer Java并发编程核心在于java.concurrent.util包 而juc当中的大多数同步器实现都是围绕着共同的基础行为,比如等待队列. ...