本人命名为 日本検索 日本搜索 (JAPAN DFS)!
以前写dfs,总是会用方向变量。今天打了这场比赛,终于知道了我在思维上的不足!日本友人的dfs思想被我充分吸收了!
怎么回是呢?快来跟小编看看吧!
这个题我很容易想到的是暴力搜索,因为数据范围很小。但又因为我很菜,尤其在思维上,没转变过来。使用方向变量后得出的结果很大,而且仔细一看,中间有空的地方根本搜不到。因为我套用的是走路径的模板。
这时候,一位日本友人的做法提醒了我。废话不多说上代码,当然这是我自己写的
#include<bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
typedef long long int ll;
const double eps = 1e-6;
const int maxn=1e5+333;
const ll mod = 1e9+7;
ll qp(ll a,ll b, ll p){ll ans = 1;while(b){if(b&1){ans = (ans*a)%p;--b;}a = (a*a)%p;b >>= 1;}return ans%p;}// a^b mod p
ll Inv(ll x){ return qp(x,mod-2,mod);}
ll C(ll n,ll m){if (m>n) return 0;ll ans = 1;for (int i = 1; i <= m; ++i) ans=ans*Inv(i)%mod*(n-i+1)%mod;return ans%mod;}
bool book[25][25] = {0};
int vis = 0;
int h,w,a,b;
ll ans = 0;
void dfs(int x,int y,int aa,int bb)
{
if(aa<0||bb<0) return;
if(y==w+1){
y = 1,x ++;
}
if(x==h+1){
ans++;
}
if(book[x][y]) return dfs(x,y+1,aa,bb);
book[x][y] = true;
dfs(x,y+1,aa,bb-1);
book[x][y] = false;
if(!book[x+1][y]&&x+1<=h){
book[x+1][y] = true;
dfs(x,y+1,aa-1,bb);
book[x+1][y] = false;
}
if(!book[x][y+1]&&y+1<=w){
book[x][y+1] = true;
dfs(x,y+1,aa-1,bb);
book[x][y+1] = false;
}
}
int main()
{
cin>>h>>w>>a>>b;
mem(book,false);
dfs(1,1,a,b);
cout<<ans<<endl;
return 0;
}
怎么样,相信屏幕前的大神一定看懂了。我仔细揣摩以后,发现了东瀛人在解题思路上的另类独特!
1.不同我的方向变量写法,这位太君使用的思想是:一直往右铺地板!当这一行铺完的时候,巧妙地初始化x,y。然后从下一行开始!
2.如果是1x2的地板,往下铺是怎么处理的呢,铺完还是往右走,因为到下一行如果开幕雷击就是已经铺好的地板,就自动往后挪到没铺的地方。
3(重点).从(1,1)开始搜索,并且回溯。如果x==h+1。说明所有行都铺完了。直接ans++。
只可意会,不可言传,日本思维果然叼,跟艺高人胆大的中国OI思想完全不一样。以后我就是日本人了!
怎么样,是不是很巧妙呢。这道题可能在大家看来是一道大水题,但对我不一样!!!
第一 我找到了算法设计中,属于我的新的思想方法和体系!把我原来破旧的老OI思想彻底更新换代!
第二 这是我在经历水题做不出来后的痛苦后的第一道题!开创了一个属于PPheng的新时代,重建长生桥的第一块砖!
激动的我兴奋的写下了这个博客,喜欢的给小编点个赞👍吧!