2021.8.19提高B组模拟9T3 + P7410 [USACO21FEB] Just Green Enough (贪心)
Posted SSL_LKJ
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021.8.19提高B组模拟9T3 + P7410 [USACO21FEB] Just Green Enough (贪心)相关的知识,希望对你有一定的参考价值。
Just Green Enough
题目
输入样例
3
57 120 87
200 100 150
2 141 135
输出样例
8
解题思路
这题我用的是贪心求解
先将区间的值改一下
=100为0,<100为-1,>100为1
-1 1 -1
1 0 1
-1 1 1
然后每一行,从右往左做前缀和(不为-1就加1,注意0也要加1)
-1 1 -1
3 2 1
-1 2 1
注:之后的事都不怎么要管-1
然后每一个不为 -1 的点向下贪心,到-1或者到底就break
期间取动态min,并相加
如**(1,2)会变成3**
因为min一直为1,共3行,加三次
1 + 1 + 1 = 3
-1 3 -1
3 4 2
-1 2 1
然后我们就可以发现每一个点的值为
当前节点为左上角的子矩阵数量(这里的子矩阵不包括-1)
答案很神奇,原因就在前面的两个贪心
ans1将他们全加起来,3 + 3 + 4 +2 + 2 + 1 = 15
接着就很好理解了
我们将之前为0的点赋值为-1
-1 1 -1
1 -1 1
-1 1 1
重复上面的推理
得到
-1 1 -1
1 -1 2
-1 2 1
ans2将他们再加起来 1 + 1 + 2 + 2 + 1 = 7
再相减,答案就是最小值为100的子矩阵数量了 15 - 7 = 8
注:记得开 long long
AC代码
#include<algorithm>
#include<cstdio>
using namespace std;
int n,a[505][505],f[505][505];
long long ans1,ans2;
void qzh()//求每一行从右往左的前缀和
{
for(int i=1;i<=n;i++)
for(int j=n;j>=1;j--)
if(a[i][j]>-1)f[i][j]=f[i][j+1]+1;
}
long long getans()
{
long long ans=0;
for(int i=1;i<=n;i++)//求答案
for(int j=1;j<=n;j++)
if(a[i][j]>-1)
{
int mmin=2147483647;
for(int k=i;k<=n;k++)
if(a[k][j]>-1)
{
mmin=min(mmin,f[k][j]);
ans+=mmin;
}
else break;
}
return ans;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
scanf("%d",&a[i][j]);
if(a[i][j]==100)a[i][j]=0;//初值
else if(a[i][j]>100)a[i][j]=1;
else a[i][j]=-1;
}
qzh();
ans1=getans();
for(int i=1;i<=n;i++)//更改
for(int j=1;j<=n;j++)
if(a[i][j]==0)a[i][j]=-1,f[i][j]=0;//清零
qzh();
ans2=getans();
printf("%lld",ans1-ans2);//答案
return 0;
}
谢谢
以上是关于2021.8.19提高B组模拟9T3 + P7410 [USACO21FEB] Just Green Enough (贪心)的主要内容,如果未能解决你的问题,请参考以下文章
2021.8.19提高B组模拟9T1 + P7411 [USACO21FEB] Comfortable Cows(dfs)
2021.8.19提高B组模拟9T1 + P7411 [USACO21FEB] Comfortable Cows(dfs)
2021.8.19提高B组模拟9T2 + P7412 [USACO21FEB] Year of the Cow (贪心)
2021.8.19提高B组模拟9T2 + P7412 [USACO21FEB] Year of the Cow (贪心)