暑假集训加试1
A. 蛋糕
区间\(DP\)板子
断环成链即可
code
#include<cstring>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
#include<set>
#include<map>
#include<random>
using namespace std;
inline int read(){
int x = 0; char c = getchar();
while(c < '0' || c > '9')c = getchar();
do{x = (x << 3) + (x << 1) + (c ^ 48); c = getchar();}while(c <= '9' && c >= '0');
return x;
}
typedef long long ll;
const int maxn = 2005;
ll f[maxn + maxn][maxn + maxn];
int a[maxn + maxn], n;
int main(){
n = read();
for(int i = 1; i <= n; ++i)a[i] = read();
for(int i = 1; i <= n; ++i)a[i + n] = a[i];
for(int len = n; len >= 1; --len){
for(int l = 1; l <= n + n - len + 1; ++l){
int r = l + len - 1;
if((n - len) & 1){
if(a[l] > a[r])f[l + 1][r] = max(f[l + 1][r], f[l][r]);
else f[l][r - 1] = max(f[l][r - 1], f[l][r]);
}else{
f[l + 1][r] = max(f[l + 1][r], f[l][r] + a[l]);
f[l][r - 1] = max(f[l][r - 1], f[l][r] + a[r]);
}
}
}
ll ans = 0;
for(int i = 1; i <= n + n; ++i)ans = max(ans, f[i][i - 1]);
printf("%lld\n",ans);
return 0;
}
B. 游戏
考场还想网络流来着,觉得不知道他是抛起来还是移动就放弃了类似思路,然而经典的拆点操作居然没有想起来.....
当然这题不用网络流,最短路即可
对每个点有三个状态\(0/1/2\)拆成\(3\)个点,\(0\)表示移动, \(1\)表示在横向抛,\(2\)表示在纵向抛
由\(0 - > 1/ 2\)连\(b\)的边
\(1/2 - > 0\)连最近的莉到该点的距离*C的边,表示由那个莉来接
相邻的\(0\)连\(c\)
相邻的\(1/2\)连\(a\)
code
#include<cstring>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
#include<set>
#include<map>
#include<random>
using namespace std;
inline int read(){
int x = 0; char c = getchar();
while(c < '0' || c > '9')c = getchar();
do{x = (x << 3) + (x << 1) + (c ^ 48); c = getchar();}while(c <= '9' && c >= '0');
return x;
}
typedef long long ll;
const int maxn = 1000005;
struct node{int x, y;}d[maxn];
ll a, b, c, ans, n;
int mp[505][505], dx[4] = {0, 0, 1, -1}, dy[4] = {1, -1, 0, 0}, X, Y;
bool check(int x, int y){return x >= 0 && x <= X && y >= 0 && y <= Y;}
queue<node>q;
struct opt{
int op, x, y; ll val;
friend bool operator < (const opt & x, const opt & y){
return x.val > y.val;
}
};
priority_queue<opt>Q;
bool vis[3][505][505];
ll dis[3][505][505];
ll dij(){
for(int i = 1; i <= n; ++i)q.push(d[i]), vis[0][d[i].x][d[i].y] = 1;
while(!q.empty()){
node now = q.front(); q.pop();
for(int i = 0; i < 4; ++i){
int nx = now.x + dx[i], ny = now.y + dy[i], nw = mp[now.x][now.y] + 1;
if(check(nx, ny) && !vis[0][nx][ny]){
vis[0][nx][ny] = 1; mp[nx][ny] = nw; q.push(node{nx, ny});
}
}
}
for(int i = 0; i <= X; ++i)
for(int j = 0; j <= Y; ++j)
vis[0][i][j] = 0;
memset(dis, 0x3f, sizeof(dis));
dis[0][d[1].x][d[1].y] = 0;
Q.push(opt{0, d[1].x, d[1].y, 0});
while(!Q.empty()){
opt now = Q.top(); Q.pop();
if(vis[now.op][now.x][now.y])continue;
vis[now.op][now.x][now.y] = 1;
if(now.op == 0){
ll change = dis[now.op][now.x][now.y] + b;
if(change < dis[1][now.x][now.y]){dis[1][now.x][now.y] = change; Q.push(opt{1, now.x, now.y, change});}
if(change < dis[2][now.x][now.y]){dis[2][now.x][now.y] = change; Q.push(opt{2, now.x, now.y, change});}
for(int i = 0; i < 4; ++i){
int nx = now.x + dx[i], ny = now.y + dy[i];
if(check(nx, ny) && dis[0][nx][ny] > dis[0][now.x][now.y] + c){
dis[0][nx][ny] = dis[0][now.x][now.y] + c;
Q.push({0, nx, ny, dis[0][now.x][now.y] + c});
}
}
continue;
}
ll ldis = dis[now.op][now.x][now.y] + mp[now.x][now.y] * c;
if(dis[0][now.x][now.y] > ldis){dis[0][now.x][now.y] = ldis;Q.push(opt{0, now.x, now.y, ldis});}
ll move = dis[now.op][now.x][now.y] + a;
if(now.op == 1){
if(check(now.x, now.y - 1) && dis[1][now.x][now.y - 1] > move){dis[1][now.x][now.y - 1] = move; Q.push(opt{1, now.x, now.y - 1, move});}
if(check(now.x, now.y + 1) && dis[1][now.x][now.y + 1] > move){dis[1][now.x][now.y + 1] = move; Q.push(opt{1, now.x, now.y + 1, move});}
}
if(now.op == 2){
if(check(now.x - 1, now.y) && dis[2][now.x - 1][now.y] > move){dis[2][now.x - 1][now.y] = move; Q.push(opt{2, now.x - 1, now.y, move});}
if(check(now.x + 1, now.y) && dis[2][now.x + 1][now.y] > move){dis[2][now.x + 1][now.y] = move; Q.push(opt{2, now.x + 1, now.y, move});}
}
}
return dis[0][d[n].x][d[n].y];
}
int main(){
X = read(), Y = read();
a = read(), b = read(), c = read();
n = read();
for(int i = 1; i <= n; ++i)d[i].x = read(), d[i].y = read();
printf("%lld\n",dij());
return 0;
}