题解:P8632 [蓝桥杯 2015 国 B] 居民集会
原题传送门
思路
我们首先用
#include<bits/stdc++.h>
#define int long long
#define inf 0x7f7f7f7f
#define mod 1000000007
using namespace std;
const int maxn = 1e6 + 100;
inline int read() {
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
return x*f;
}
int dp[maxn][5] , n , l , ll = 1 , rr = 0 , q[maxn] , sumt[maxn] , d[maxn] , t , sumdt[maxn] , f[maxn];
signed main(){
n = read();
l = read();
for(int i = 1; i <= n; i++) {
d[i] = read();
t = read();
sumt[i] = sumt[i - 1] + t;
sumdt[i] = sumdt[i - 1] + d[i] * t;
}
n++;
d[n] = l;
sumt[n] = sumt[n - 1];
sumdt[n] = sumdt[n - 1];
memset(dp , 0x3f , sizeof(dp));
dp[1][1] = 0;
dp[0][0] = 0;
for(int i = 1; i <= 4; i++) {
for(int j = 1; j <= n; j++) {
for(int k = 0; k < j; k++) {
dp[j][i] = min(dp[j][i] , dp[k][i - 1] + d[j] * (sumt[j] - sumt[k]) - (sumdt[j] - sumdt[k]));
}
}
}
cout << dp[n][4] << endl;
return !("wjl1100 qwq");
}
这样我们就可以得到 50 分。
(以下的
#include<bits/stdc++.h>
#define int long long
#define inf 0x7f7f7f7f
#define mod 1000000007
using namespace std;
const int maxn = 1e6 + 100;
inline int read() {
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
return x*f;
}
int dp[maxn][5] , n , l , ll = 1 , rr = 0 , q[maxn] , sumt[maxn] , d[maxn] , t , sumdt[maxn];
inline int getg(int i , int k) {
return dp[i][k] + sumdt[i];
}
inline long double getxl(int i , int j , int k) {
if(sumt[i] == sumt[j]) return inf;
return (long double) (getg(j , k) - getg(i , k)) / (sumt[j] - sumt[i]);
}
signed main(){
n = read();
l = read();
for(int i = 1; i <= n; i++) {
d[i] = read();
t = read();
sumt[i] = sumt[i - 1] + t;
sumdt[i] = sumdt[i - 1] + d[i] * t;
}
n++;
d[n] = l;
sumt[n] = sumt[n - 1];
sumdt[n] = sumdt[n - 1];
memset(dp , 0x7f , sizeof(dp));
dp[0][0] = 0;
for(int time = 1; time <= 4; time++) {
ll = 1;
rr = 0;
q[++rr] = 0;
for(int i = 1; i <= n; i++) {
while(rr > ll && getxl(q[ll] , q[ll + 1] , time - 1) <= d[i]) ll++;
int u = q[ll];
dp[i][time] = dp[u][time - 1] + d[i] * (sumt[i] - sumt[u]) - (sumdt[i] - sumdt[u]);
while(rr > ll && getxl(q[rr - 1] , q[rr] , time - 1) >= getxl(q[rr] , i , time - 1)) rr--;
q[++rr] = i;
}
}
cout << dp[n][4] << endl;
return !("wjl1100 qwq");
}
三倍经验:
居民集会
仓库建设
锯木厂选址