链接
来源:牛客网
题目描述
罗德岛训练室今天的使用人是干员w,她的任务是使用手上的三个遥控炸弹,尽可能摧毁最大价值的目标。
测试区域是一个nn的矩阵,w可以选择任意格子安放炸弹,如果选择了位置[i][j]安放炸弹,那么对于所有的[i][k]满足|k-j|<=2和所有[l][j]满足|l-i|<=2的点,都会被这个炸弹所摧毁。也就是说炸弹安放位置以及其上下左右各向外延伸2个单位长度的格子都会被其摧毁,重复被摧毁的格子只计算一次该格子的价值。
(如下图所示,如果在该55矩阵的中心位置安放炸弹,除了安放的位置外,四个方向上8个画X的位置也会被摧毁)
睿智的勃士总是能帮助w快速计算出可以摧毁的最大价值。
输入描述:
第一行为一个整数n,代表矩阵的宽度。(1<=n<=10)
接下来第1+i行(1<=i<=n),每行为空格隔开的n个整数a[i][j]。代表矩阵位置[i][j]的价值是多少。(0<=a[i][j]<=1e9)
输出描述:
输出一个整数,代表能摧毁的最大价值。
示例1
输入
5
2 2 2 2 2
2 0 2 0 2
2 2 2 2 2
2 0 2 0 2
2 2 2 2 2
输出
34
说明
有多种安放选择均可摧毁价值34,其中一种方案是炸弹放置在(3,1),(3,3),(3,5)
示例2
输入
8
10 15 3 3 12 16 7 2
1 6 19 19 1 12 19 14
7 0 6 3 15 1 16 2
13 7 12 5 2 9 2 5
13 0 14 6 19 10 9 1
0 13 1 1 14 15 7 7
1 12 3 16 12 14 12 9
11 15 16 14 1 12 1 8
输出
280
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
//这个数组需要主要加上原点
int dir[9][2]={{-1,0},{1,0},{0,-1},{0,1},{-2,0},{2,0},{0,-2},{0,2},{0,0}};
int vis[15][15];
ll a[15][15];
int n;
ll ans=0,res=0;
void start(int x,int y){
for(int i=0;i<9;i++){
int nx=x+dir[i][0];
int ny=y+dir[i][1];
if(nx<1||nx>n||ny<1||ny>n) continue;
if(vis[nx][ny]==0) ans+=a[nx][ny];
vis[nx][ny]++;
}
}
void back(int x,int y){
for(int i=0;i<9;i++){
int nx=x+dir[i][0];
int ny=y+dir[i][1];
if(nx<1||nx>n||ny<1||ny>n) continue;
vis[nx][ny]--;
if(vis[nx][ny]==0) ans-=a[nx][ny];
}
}
void dfs(int k){
if(k==3){
res=max(ans,res);
return;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
start(i,j);//爆炸当前位置
dfs(k+1);
back(i,j);//回到爆炸前的状态
}
}
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>a[i][j];
}
}
memset(vis,0,sizeof(vis));
dfs(0);
cout<<res<<endl;
return 0;
}
/*
5
2 2 2 2 2
2 0 2 0 2
2 2 2 2 2
2 0 2 0 2
2 2 2 2 2
*/
总结:
比赛的时候思想出问题了,往动态规划的方向想了。
最后才发现,这根本就是个暴力题嘛。
每次选点就暴力一次就完事了,可以把所有的点都算上,毕竟数据小,不用考虑重复的情况