FB!
懒 直接搬题解吧
先令fn,m表示n∗m的网格能排序的最大数量
我们把左上角这一格里的数 按大小分到其他块中 其中(i,j)最多放fn−i+1,m−j+1个 然后递归的做就好了
我们发现某根柱子就算本来有东西也毫不影响 踩上去就是了
这样是
fn,m=∑i=1n∑j=1mfi,j i≠n or j≠mf1,1=1
这样f6,6是2w+ 还不够
但是这样就可以4w+辣
fn,m=∑i=1n∑j=1mfi,j i≠n or j≠mf1,1=1,f1,2=f2,1=2
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<vector>
#define pb push_back
using namespace std;
#define read(x) scanf("%d",&(x))
inline void write(int x) {
if (!x) return (void) printf("0");
if (x < 0) putchar('-'), x = -x;
static short s[12], t;
while (x) s[++t] = x % 10, x /= 10;
while (t) putchar('0' + s[t--]);
}
const int f[7][7]={
{0,0,0,0,0,0,0},
{0,1,2,3,6,12,24},
{0,2,5,13,32,76,176},
{0,3,13,42,122,332,864},
{0,6,32,122,404,1228,3520},
{0,12,76,332,1228,4104,12792},
{0,24,176,864,3520,12792,42960}
};
inline void P(int x,int y,char c,int z){
printf("%d %d %c %d\n",x,y,c,z);
}
inline void move(int x1,int y1,int x2,int y2){
while (x1<x2) P(x1,y1,'D',1),x1++;
while (y1<y2) P(x1,y1,'R',1),y1++;
}
const int N=40005;
int pre[7][7];
int px[N],py[N];
inline void Solve(int x,int y,int n,int m,vector<int> &v){
if (n*m==1) return;
if (n*m==2){
if (v.size()==1) P(x,y,n==1?'R':'D',1);
else{
if (v[0]==2) P(x,y,n==1?'R':'D',2);
else P(x,y,n==1?'R':'D',1),P(x,y,n==1?'R':'D',1);
}
return;
}
vector<int> _v[7][7];
int pt=v.size();
for (int i=n;i && pt;i--)
for (int j=m;j && pt;j--){
if (i*j==1) continue;
int f=min(::f[n-i+1][m-j+1],pt);
for (int k=1;k<=f;k++) px[pt]=i,py[pt]=j,pt--;
pre[i][j]=pt;
}
for (int i=(int)v.size()-1;~i;i--){
int t=v[i];
move(x,y,x+px[t]-1,y+py[t]-1);
_v[px[t]][py[t]].pb(t-pre[px[t]][py[t]]);
}
for (int i=n;i;i--)
for (int j=m;j;j--)
if (_v[i][j].size())
Solve(x+i-1,y+j-1,n-i+1,m-j+1,_v[i][j]);
}
int main(){
int a,n;
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
read(n);
vector<int> v;
for (int i=1;i<=n;i++) read(a),v.pb(a);
Solve(1,1,6,6,v);
return 0;
}
本文介绍了一种基于递归思想的网格排序算法,该算法通过将网格中的元素按大小分配到不同的区块来实现最大数量的排序。文章详细阐述了算法的具体实现过程,并提供了完整的代码示例。

425

被折叠的 条评论
为什么被折叠?



