题意:
给一个n*m的方格,每个方格里有一个数字(范围0~9),现在给一个集合vector_x,和vector_y,分别表示每个点可以覆盖的点集(i+vector_x[],j+vector_y[]),且vector_x和vector_y的大小不超过10。现在让你选两个点,让这两个点覆盖的所有点的权值和最大(被重复覆盖的点,只计算一次)。
范围:0<n,m<=100;
分析:
最暴力的方法:直接枚举两个点,然后求权值之和,复杂度为100*100*100*100*10,肯定超时。
题目中数据范围较小的条件,很可能是题目的突破口,vector_x和vector_y的范围最大为10,我们将从这里突破。
首先看一下一个点最多可以被多少个不同的点覆盖,因为vector_x和vector_y的范围都是10,所以可以得知,每个点最多可以被10个不同的点覆盖。
在方格中选一个点(i,j),把他覆盖的10个点当作一个状态,那么最多有多少状态和他有交集,可以大致判断为100个。
题目转化为从100*100个状态中,选择两个状态,权值最大。
做法:
首先预处理出100*100个状态,然后从大到小排序,则前101个状态中,肯定有不相交的状态,然后只需枚举前101个状态,然后判断,求解出最大值。
复杂度:预处理:100*100*10,排序:100*100*log(100*100),求解:101*101*10
//这题思路较好,这里我只写出了思路分析,代码取自:http://blog.csdn.net/madaidao/article/details/46373655
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <sstream>
#define OUT(x) cout << #x << ": " << (x) << endl
#define SZ(x) ((int)x.size())
#define FOR(i, n) for (int i = 0; i < (n); ++i)
const int inf=0x3fffffff;
using namespace std;
typedef long long LL;
struct node
{
int u,v;
int val;
node(){}
node(int uu,int vv,int vall)
{
u=uu,v=vv,val=vall;
}
}b[11000];
bool use[110][110];
bool cmp(node x,node y)
{
return x.val>y.val;
}
class Coversta
{
public:
int place(vector <string> a, vector <int> x, vector <int> y)
{
int n=a.size(),m=a[0].size();
int l=x.size();
int num=0;
int i,j,k;
int ix,dx,dy;
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
ix=0;
for(k=0;k<l;k++)
{
dx=i+x[k];
dy=j+y[k];
if(dx>=0&&dx<n&&dy>=0&&dy<m)
{
ix+=a[dx][dy]-'0';
}
}
b[num++]=node(i,j,ix);
}
}
int ans=-inf;
sort(b,b+num,cmp);
memset(use,false,sizeof(use));
for(i=0;i<min(num,100);i++)
{
for(k=0;k<l;k++)
{
dx=b[i].u+x[k];
dy=b[i].v+y[k];
if(dx>=0&&dx<n&&dy>=0&&dy<m)
use[dx][dy]=true;
}
for(j=i+1;j<min(num,100);j++)
{
if(b[i].val+b[j].val<=ans)
break;
ix=b[i].val;
for(k=0;k<l;k++)
{
dx=b[j].u+x[k];
dy=b[j].v+y[k];
if(dx>=0&&dx<n&&dy>=0&&dy<m)
{
if(!use[dx][dy])
{
ix+=a[dx][dy]-'0';
}
}
}
ans=max(ans,ix);
}
for(k=0;k<l;k++)
{
dx=b[i].u+x[k];
dy=b[i].v+y[k];
if(dx>=0&&dx<n&&dy>=0&&dy<m)
use[dx][dy]=false;
}
}
return ans;
}
};