今天robocom国赛,因为一个bool函数忘记return 1而裂开(错失21分)
以此为戒
贪心消消乐
其实就是一个求最大子矩阵和的板子题
利用最大子段和的思想
枚举矩阵中的上下界
压成一维后利用最大子段和
O
(
n
)
O(n)
O(n)处理
复杂度
O
(
n
3
∗
k
)
O(n^3*k)
O(n3∗k)
k为执行次数
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 5010;
int a[N][N];
int n;
int sum[N][N];
int maxn = 0;
int s[N][N],ss[N][N];
int tot = 0;
int stx,sty,edx,edy,xx,XX,yy,YY;
int cnt = 0;
void Swap(){
xx = sty; XX = edy; yy = stx; YY = edx;
}
int ce =0 ;
bool Work(){
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++){
s[j][i] = s[j][i-1]+a[i][j];
ss[j][i] = ss[j][i-1];
if (a[i][j] == 0) ss[j][i]++;
}
int maxx = 0;
xx = n+1; yy = n+1; XX = n+1; YY = n+1;
for (stx = 1; stx <= n; stx++){
for (edx = stx; edx <= n; edx++){
int sum = 0;
sty = 1;
for (edy = 1; edy <= n; edy++){
if (sum > maxx) Swap();
int now = s[edy][edx]-s[edy][stx-1];
int nowz = ss[edy][edx]-ss[edy][stx-1];
if (nowz!=0){
sty = edy+1;
sum = 0;
continue;
}
if (sum < 0){
sum = 0;
sty = edy;
}
sum+=now;
if (sum > maxx) maxx = sum,Swap();
if (sum == maxx){
if (sty < xx) Swap();
else if (sty == xx&&stx < yy) Swap();
else if (sty == xx && stx == yy&&edy < XX) Swap();
else if (sty == xx && stx == yy&&edy == XX && edx < YY) Swap();
}
}
}
}
if (maxx == 0) return 0;
tot+=maxx;
printf("(%lld, %lld) (%lld, %lld) %lld\n",xx,yy,XX,YY,maxx);
swap(xx,yy); swap(XX,YY);
int delx = XX-xx+1;
for (int i = xx-1; i >= 1; i--)
for (int j = yy; j <= YY; j++)
a[i+delx][j] = a[i][j];
for (int i = 1; i <= delx; i++)
for (int j = yy; j <= YY; j++) a[i][j] = 0;
cnt++;
bool f = 0;
return 1;
}
signed main(){
cin>>n;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++){
cin>>a[i][j];
if (a[i][j] > 0) maxn+=a[i][j],ce++;
}
while (Work()); cout<<tot<<endl;
}
拍照
一道最大权值闭合图的板子题
按如下方式连边:
最大全职就是
s
u
m
−
m
a
x
f
l
o
w
sum-maxflow
sum−maxflow
证明尚未完全理清
等我理清了来补
#include<bits/stdc++.h>
using namespace std;
const int N = 7e3+100,inf = 1e9+7;
struct Node{
int y,Next,v;
}e[2*N];
int len,Linkk[N];
int st,ed;
void Insert(int x,int y,int v){
e[++len] = (Node){y,Linkk[x],v};
Linkk[x] = len;
}
queue < int > q;
int d[N];
bool bfs(){
for (int i = 1; i <= ed; i++) d[i] = 0;
while (q.size()) q.pop();
d[st] = 1; q.push(st);
while (q.size()){
int x = q.front(); q.pop();
for (int i = Linkk[x]; i; i = e[i].Next){
int y = e[i].y; if (!e[i].v ||d[y]) continue;
d[y] = d[x]+1; q.push(y);
if (y == ed) return 1;
}
}
return 0;
}
int dinic(int x,int flow){
if (x == ed) return flow;
int re = flow , k;
for (int i = Linkk[x]; i; i = e[i].Next){
int y = e[i].y; if (!e[i].v || d[y] != d[x]+1) continue;
k = dinic(y,min(re,e[i].v));
if (!k) d[y] = 0;
re-=k;
e[i].v-=k; e[i^1].v+=k;
}
return flow-re;
}
int n,m;
int main(){
cin.tie(0);
ios::sync_with_stdio(false);
cin>>m>>n; len = 1;
st = n+m+1; ed = n+m+2;
int sum = 0;
for (int i = 1; i <= m; i++){
int v; cin>>v; sum+=v;
Insert(st,i,v); Insert(i,st,0);
int x;
cin>>x;
while (x){
Insert(i,x+m,inf); Insert(x+m,i,0);
cin>>x;
}
}
for (int i = m+1,x; i <= m+n; i++)
cin>>x,Insert(i,ed,x),Insert(ed,i,0);
int flow;
int maxf = 0;
while (bfs())
while (flow = dinic(st,inf)) maxf+=flow;
cout<<sum-maxf<<endl;
return 0;
}
太空飞行计划问题
与上体一样
所多的就是输出方案
这里最大流用的是dinic算法
如果最后对于一个点i,d[i]不为0,说明这个点在分层图中出现,并且用上了
那么就说明这个仪器用上了
#include<bits/stdc++.h>
using namespace std;
const int N = 7e3+100,inf = 1e9+7;
struct Node{
int y,Next,v;
}e[2*N];
int len,Linkk[N];
int st,ed;
void Insert(int x,int y,int v){
e[++len] = (Node){y,Linkk[x],v};
Linkk[x] = len;
}
queue < int > q;
int d[N];
bool bfs(){
for (int i = 1; i <= ed; i++) d[i] = 0;
while (q.size()) q.pop();
d[st] = 1; q.push(st);
while (q.size()){
int x = q.front(); q.pop();
for (int i = Linkk[x]; i; i = e[i].Next){
int y = e[i].y; if (!e[i].v ||d[y]) continue;
d[y] = d[x]+1; q.push(y);
if (y == ed) return 1;
}
}
return 0;
}
int dinic(int x,int flow){
if (x == ed) return flow;
int re = flow , k;
for (int i = Linkk[x]; i; i = e[i].Next){
int y = e[i].y; if (!e[i].v || d[y] != d[x]+1) continue;
k = dinic(y,min(re,e[i].v));
if (!k) d[y] = 0;
re-=k;
e[i].v-=k; e[i^1].v+=k;
}
return flow-re;
}
int flag;
int re(){
char c;int r=0;
while (c<'0' || c>'9') c=getchar();
while (c>='0' && c<='9')
{
r=r*10+c-'0';
c=getchar();
}
if (c=='\r') flag=1;
return r;
}
int n,m;
int main(){
// cin.tie(0);
// ios::sync_with_stdio(false);
scanf("%d %d",&m,&n); len = 1;
st = n+m+1; ed = n+m+2;
int sum = 0;
for (int i = 1; i <= m; i++){
int v; scanf("%d",&v); sum+=v;
Insert(st,i,v); Insert(i,st,0);
int x; flag = 0;
while (getchar() == ' '){
scanf("%d",&x);
Insert(i,x+m,inf); Insert(x+m,i,0);
// cout<<"x = "<<x<<endl;
}
}
// cout<<"OK";
for (int i = m+1,x; i <= m+n; i++)
scanf("%d",&x),Insert(i,ed,x),Insert(ed,i,0);
int flow;
int maxf = 0;
while (bfs())
while (flow = dinic(st,inf)) maxf+=flow;
for (int i = 1; i <= m; i++) if (d[i]) cout<<i<<' ';
cout<<endl;
for (int i = 1; i <= n; i++) if (d[i+m]) cout<<i<<' '; cout<<endl;
cout<<sum-maxf<<endl;
return 0;
}