題意:
給你一個的地圖,有一些不能到達的點,用#表示,有個人要從到點,你可以將其中任意點變成#,問你最少將多少個點變成#可以讓這個人無法到達
分析與解答
①對於一開始便無法到達的點來說,不需要變任何一個
②因爲點在左下角,我們只要放置與兩個就可以不讓他到達
因此只需要考慮是否只放一個點就能夠阻止他
我們考慮兩個數組,意義如下:
dp[i][j]:從(1,1)到(i,j)有多少種走法
dp1[i][j]:從到有多少種走法,也就是從到有多少種走法
對於一個點來說,如果滿足,則我們根據乘法定理,可以知道該點一定是一個必經點
同時考慮到數據範圍的問題,我們利用哈希的思想,對數組取模,如果在模和模的意義下,其中,該點都滿足上邊的等式,則該點爲必經點
代碼
/*************************************************************************
> File Name: 2019_9_4_4.cpp
> Author: z472421519
> Mail:
> Created Time: 2019年09月04日 星期三 18時10分04秒
************************************************************************/
#include <bits/stdc++.h>
#include <cstdio>
#include <cstring>
#define MAXN 1000003
#define mod 1000000017
#define mod1 1000000007
#define ll long long
using namespace std;
vector <ll> dp[MAXN];
vector <ll> dp1[MAXN];
vector <ll> dp_[MAXN];
vector <ll> dp1_[MAXN];
string s[MAXN];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
dp[1].push_back(1);
dp_[1].push_back(1);
//dp[1].push_back(1);
for(int i = 1;i <= n;i++)
{
//rintf("T\n");
cin >> s[i];
//printf("T\n");
for(int j = 0;j < m;j++)
{
dp1[i].push_back(0);
dp1_[i].push_back(0);
//printf("%d\n",i);
if(i == 1 && j == 0)
continue;
if(s[i][j] == '#')
{
dp[i].push_back(0);
dp_[i].push_back(0);
}
else
{
ll res = 0,res_ = 0;
if(i > 1)
{
res += dp[i - 1][j];
res_ += dp_[i - 1][j];
}
res %= mod;
res_ %= mod1;
if(j > 0)
{
res += dp[i][j - 1];
res_ += dp_[i][j - 1];
}
res %= mod;
res_ %= mod1;
dp[i].push_back(res);
dp_[i].push_back(res_);
}
}
//printf("%d\n",dp[n][m - 1]);
}
if(dp[n][m - 1] == 0 && dp_[n][m - 1] == 0)
printf("0\n");
else
{
int ans = 2;
dp1[n][m - 1] = 1;
dp1_[n][m - 1] = 1;
//printf("%d\n",dp1[n][m - 1]);
for(int i = n;i >= 1;i--)
{
for(int j = m - 1;j >= 0;j--)
{
if(i == 1 && j == 0)
continue;
if(i == n && j == m - 1)
continue;
if(s[i][j] == '#')
{
dp1[i][j] = 0;
dp1_[i][j] = 0;
}
else
{
ll res = 0,res_ = 0;
if(i < n)
{
res += dp1[i + 1][j];
res_ += dp1_[i + 1][j];
}
res %= mod;
res_ %= mod1;
if(j < m - 1)
{
res += dp1[i][j + 1];
res_ += dp1_[i][j + 1];
}
res %= mod;
res_ %= mod1;
dp1[i][j] = res;
dp1_[i][j] = res_;
//printf("%d %d\n",i,j,dp[i][j],dp1[i][j],dp[n][m - 1]);
if((dp1[i][j] * dp[i][j]) % mod == dp[n][m - 1] && (dp1_[i][j] * dp_[i][j]) % mod1 == dp_[n][m - 1])
{
ans = 1;
break;
}
//printf("%d %d %d %d\n",i,j,dp[i][j],dp1[i][j]);
}
}
if(ans == 1)
break;
//printf("%d %d %d %d\n",i,j,dp[i][j],dp1[i][j]);
}
printf("%d\n",ans);
}
return 0;
}