1. 程式人生 > >[dp]vijos1063 迎春舞會之集體舞

[dp]vijos1063 迎春舞會之集體舞

printf can map bsp .cn 計算 sca jos 陰影

題目梗概

一個大的三角形,其中有向下的正三角形和向上的正三角形。求最大的正三角的組成人數(陰影部分不能算入)

思考

這道題目卡了我好長時間,題目和之前做過的最大正方形有異曲同工之妙。只不過這道題目需要額外的處理一下。

首先我們看下向下的正三角如何求?

手動模擬會發現,和最大正方形類似。在i行j列的三角形的大小是受 (i-1,j) (i-1,j+1) (i-1,j-1) 這三個三角形的限制。這個我就不證明了。。

不過需要註意的是只有向下的三角形才能組成正三星形,這個怎麽處理呢?每次記錄Max值的之後判斷一下這個三角形是不是向下的就可以了,如果不是就不用記錄。

為什麽?看著組數據


10
------------#####--
--#-----#-#--#---
--#----#---#---
-------#--#--
--#-#------
-----##--
---#---
-----
---
-

技術分享

因為我們是在計算向下的三角形,所以不應該去考慮向上的三角形,但是不能忽略它的dp值,因為向上向下的三角形是一起參與構圖的。

另一個同樣方法。

代碼實現

#include <cstdio>
#include <cstring>
#include 
<algorithm> int n,map[105][205],dp[105][205],Max=-1; char s[233]; int main(){ memset(dp,0,sizeof(dp)); memset(map,0,sizeof(map)); scanf("%d",&n); int pos = n*2+1; for(int i=1;i<=n;i++){ scanf("%s",s+1); for(int j=1;j<=pos-i*2;j++){
if(s[j]==-) map[i][j+i-1]=1; } } for(int i=1;i<=n;i++){ for(int j=i;j<=n*2-i;j++){ if(map[i][j]){ dp[i][j] = std::min(dp[i-1][j],std::min(dp[i-1][j+1],dp[i-1][j-1]))+1; if( (j-i+1)&1 )Max = std::max(dp[i][j],Max);//判斷奇偶 } } } //記得賦值 memset(dp,0,sizeof(dp)); for(int i=n;i>=1;i--){ for(int j=i;j<=n*2-i;j++){ if(map[i][j]){ dp[i][j] = std::min(dp[i+1][j],std::min(dp[i+1][j+1],dp[i+1][j-1]))+1; if( !((j-i+1)&1) )Max = std::max(dp[i][j],Max);//偶數就判斷 } } } //正三角形這個計算沒啥說的 printf("%d\n",Max*Max); }

[dp]vijos1063 迎春舞會之集體舞