P1387 最大正方形
P1387 最大正方形 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
将当前点作为正方形的右下角点,判断它可以扩展成边长为多大的点,找到最大正方形。
此时需要判断它的上方,左方和左上方最多可以延申多长,则该点作为右下角的最大正方形边长为这三个方向的最小值加一。
#include<bits/stdc++.h>
using namespace std;
int a[105][105],sq[105][105];
int main()
{
int i,j,n,m,max=0;
cin>>n>>m;
for(i=1;i<=n;i++){
for(j=1;j<=m;j++)
cin>>a[i][j];
}
for(i=1;i<=n;i++){
for(j=1;j<=m;j++)
{
if(a[i][j]==1)//判断能否扩展
{
sq[i][j]=min(min(sq[i-1][j],sq[i][j-1]),sq[i-1][j-1])+1;//转移方程
if(sq[i][j]>max)max=sq[i][j];//跟新最大值
}
}
}
cout<<max;
}
P1934 封印
P1934 封印 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
前面的结果不会影响到后面的结果,依次求出最外层到最里层的消耗量,在每一层都判断是否可以和前面的封印一起解除,这样的消耗更小然后可以更新最小值。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[10000],f[10000],s[10000];
int main()
{
ll i,j,t,n,sum=0;
cin>>n>>t;
for(i=1;i<=n;i++)
cin>>a[i];
s[1]=a[1];
for(i=2;i<=n;i++)
{
s[i]=a[i]+s[i-1];//前缀和数组
}
for(i=1;i<=n;i++)
{
f[i]=a[i]*n*n+f[i-1];//不连续时的消耗
for(j=1;j<i;j++)
{
if(a[j]+a[i]>t)continue;//寻找可以连续破除的地方
else
{
f[i]=min(f[i],+f[j-1]+(s[i]-s[j-1])*(a[j]+a[i])); //转移方程
}
}
}
cout<<f[n];
}