您的位置:首页 > 其它

Codeforces 611C New Year and Domino DP+前缀和

2016-12-29 22:32 477 查看
点击打开链接

题意:

给你个矩阵,每个位置是空或者不空
每两个相邻空的位置,可以放一个木条
有q次询问,每次问你一个子矩阵中,放一根木条有多少种放法
//q<=1e5 1<=w,h<=500 3秒时限 
O(2wh+q(w+h)) 约为1e7


定义好状态即可:/f[i][j] 第i行横着放,前j列&&以第j列为终点(第2个'.'在第j列上)连续2个.的个数 

//cos A=(b2+c2-a2)/2bc
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N=6e2+20;
char g

;
int h,w;
int f

,d

;//f[i][j] 第i行横着放,前j列&&以第j列为终点(第2个'.'在第j列上)连续2个.的个数

void init()
{
memset(f,0,sizeof(f));
memset(d,0,sizeof(d));
for(int i=1;i<=h;i++)
{
f[i][0]=0;
f[i][1]=0;
for(int j=2;j<=w;j++)
{
if(g[i][j]=='.'&&g[i][j-1]=='.')
f[i][j]=f[i][j-1]+1;
else
f[i][j]=f[i][j-1];

//cout<<f[i][j]<<' ';
}
//cout<<endl;
}

for(int j=1;j<=w;j++)
{
d[0][j]=0;
d[1][j]=0;
for(int i=2;i<=h;i++)
{
if(g[i][j]=='.'&&g[i-1][j]=='.')
d[i][j]=d[i-1][j]+1;
else
d[i][j]=d[i-1][j];
}
}
}
int main()
{

while(scanf("%d%d",&h,&w)!=EOF)
{
for(int i=1;i<=h;i++)
scanf("%s",g[i]+1);

init();

int q;
scanf("%d",&q);
//q<=1e5 1<=w,h<=500 3秒时限
//O(2wh+q(w+h)) 1e7
while(q--)
{
int r1,c1,r2,c2;
scanf("%d%d%d%d",&r1,&c1,&r2,&c2);

int ans=0;
for(int i=r1;i<=r2;i++)
ans+=f[i][c2]-f[i][c1];

for(int j=c1;j<=c2;j++)
ans+=d[r2][j]-d[r1][j];

cout<<ans<<endl;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: