您的位置:首页 > 其它

51nod 1580 铺管道

2017-06-27 22:34 316 查看
分三种情况讨论:

1.直线

2.折一次的折线

3.折2次的折线

有点麻烦的题//#include<bits/stdc++.h>
#include<stdio.h>
#include<cstring>
using namespace std;

const int MAXN=2020;
char mp[MAXN][MAXN];
int dp[4][MAXN][MAXN],cdp[2][MAXN][MAXN];

int main()
{
long long n,m,i,j;
long long ans;
while(~scanf("%lld%lld",&n,&m))
{
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
scanf(" %c",&mp[i][j]);

for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
if(mp[i][j]=='.')
{
if(i==1)
dp[0][i][j]=1;
else
dp[0][i][j]=dp[0][i-1][j];
if(j==1)
dp[1][i][j]=1;
else
dp[1][i][j]=dp[1][i][j-1];
}
else
dp[0][i][j]=dp[1][i][j]=0;
}
}
for(i=n;i>=1;i--)
{
for(j=m;j>=1;j--)
{
if(mp[i][j]=='.')
{
if(i==n)
dp[2][i][j]=1;
else
dp[2][i][j]=dp[2][i+1][j];
if(j==m)
dp[3][i][j]=1;
else
dp[3][i][j]=dp[3][i][j+1];
}
else
dp[2][i][j]=dp[3][i][j]=0;
}
}
ans=0;
for(i=2;i<n;i++)
{
if(dp[1][i][m])
ans++;
}
for(j=2;j<m;j++)
{
if(dp[0]
[j])
ans++;
}
for(i=2;i<n;i++)
{
for(j=2;j<m;j++)
{
if(dp[0][i][j]&&dp[1][i][j])
ans++;
if(dp[0][i][j]&&dp[3][i][j])
ans++;
if(dp[2][i][j]&&dp[1][i][j])
ans++;
if(dp[2][i][j]&&dp[3][i][j])
ans++;
}
}
memset(cdp,0,sizeof(cdp));
for(i=2;i<n;i++)
{
for(j=2;j<m;j++)
{
cdp[0][i][j]+=dp[0][i][j]+dp[2][i][j];
ans+=cdp[0][i][j]*cdp[0][i][j-1];
if(j>=3)
ans-=dp[0][i][j-1]*dp[0][i][j]+dp[2][i][j-1]*dp[2][i][j];
if(mp[i][j]=='.')
cdp[0][i][j]+=cdp[0][i][j-1];

cdp[1][i][j]+=dp[1][i][j]+dp[3][i][j];
ans+=cdp[1][i][j]*cdp[1][i-1][j];
if(i>=3)
ans-=dp[1][i-1][j]*dp[1][i][j]+dp[3][i-1][j]*dp[3][i][j];
if(mp[i][j]=='.')
cdp[1][i][j]+=cdp[1][i-1][j];
}
}
printf("%lld\n",ans);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  51nod dp