Gym - 101615J Grid Coloring DP 2017-2018 ACM-ICPC Pacific Northwest Regional Contest (Div. 1)
阿新 • • 發佈:2018-08-28
bitset typedef src order esp red memset return sizeof
題目傳送門
題目大意:
給出n*m的網格,有紅藍兩種顏色,每個格子都必須被染色,當一個格子被染成藍色後,這個格子左上方的一塊都必須被染成藍色,問最後的方案數量。
思路:
按照題目條件,如果有一個格子被染成了紅色,則這個格子的右下方要全部被染成紅色,也就是這個給出的網格能讓我們染色的,是一個左上方和右下方都是階梯型的圖形,而對於每一行來說,當一個格子被染成了藍色,那麽左邊的所有格子都必須被染成藍色,所以我們設 f[ i ][ j ] 表示第 i 行 第 j 個格子被染成藍色的方案數量,那麽這個dp方程就是 f[ i ][ j ] += f[ i+1 ][ k ](0<=k<=m)。
而對於每一行,我們可以預處理出這一行的能填藍色的左右邊界,最下面一行能填顏色的賦值為1(註意,f [ n ][ 0 ]也要賦值,這表示這一行全填為紅色)。
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<string.h> #include<sstream> #include<set> #include<map> #include<vector> #include<queue> #include<stack> #include<bitset> #include<unordered_map> #defineView CodeCLR(a,b) memset((a),(b),sizeof((a))) using namespace std; typedef long long ll; inline int rd() { int f = 1; int x = 0; char s = getchar(); while (s<‘0‘ || s>‘9‘) {if (s == ‘-‘)f = -1;s = getchar();} while (s >= ‘0‘&&s <= ‘9‘) {x = x * 10 + s - ‘0‘;s = getchar();} x*= f;return x;} inline ll gcd(ll a, ll b) { if (b == 0)return a; return gcd(b, a%b); } int n,m; char mp[40][40]; int l[40],r[40]; ll f[40][40]; int flag=0; int main() { scanf("%d%d",&n,&m); for(int i=1; i<=n; i++) { scanf("%s",mp[i]+1); l[i]=0,r[i]=m; for(int j=1; j<=m; j++) { if(mp[i][j]==‘B‘) l[i]=max(l[i], j ); if(mp[i][j]==‘R‘) r[i]=min(r[i], j - 1); } if(r[i]<l[i])flag=1; } if(flag) { printf("0\n"); return 0; } for(int i=l[n]; i<=r[n]; i++) { f[n][i]=1; } for(int i=n-1; i>=1; i--) { for(int j=l[i]; j<=r[i]; j++) { for(int k=l[i+1]; k<=r[i+1]&&k<=j; k++) { f[i][j]+=f[i+1][k]; } } } ll sum=0; for(int i=0; i<=m; i++)sum+=f[1][i]; printf("%lld\n",sum); }
Gym - 101615J Grid Coloring DP 2017-2018 ACM-ICPC Pacific Northwest Regional Contest (Div. 1)