分析:一開始拿到這道題真的是無從下手,暴力都很難打出來.但是基本的方向還是要有的,題目問的是方案數,dp不行就考慮數學方法.接下來比較難想.其實對於每一行或者每一列,我們任意打亂順序其實對答案是沒有影響的.那麼我們按照高度從大到小對行和列進行排序,單獨考慮所有高度相等的行和列,組成了乙個l形,如果我們把所有的l形的方案數求出來最後乘起來就是答案了,關鍵就是怎麼求它的方案數.
要求l形中滿足每行每列最大高度不超過h的方案數很難求,因為不好保證最大高度,正難則反,先求出不滿足的,但是不滿足的也比較難求,我們就先求出有一行不滿足的,一列不滿足的,然後求出兩行不滿足的,兩列不滿足的,這其實就是乙個容斥原理,處於限制的行和列由於取的數小於h,所以每一位能取h個數,而沒有限制的可以取0~h,共h+1個數,那麼方案數就出來了:h^(限制的面積) + (h+1)^(沒有限制的面積)* (-1)^|s|,就像下面乙個圖:
藍色部分沒有限制,黑色部分有限制,黑色部分和藍色部分組成了乙個l形.
正難則反,如果求滿足某某條件很難,就求出不滿足某某條件的,如果還是很難,就分解一下,利用容斥原理來做.
#include #include#include
#include
using
namespace
std;
const
int mod = 1e9 + 9
;long
long n, m,a[10010],b[10010
],x,y;
long
long ans = 1,c[100][100
];void
init()
}long
long qpow(long
long a, long
long
b)
return
res;
}long
long cal(long
long x, long
long y, long
long nx, long
long ny, int
p) }
return
res;
}int
main()
for (int i = 1; i <= m; i++)
init();
for (int i = 10000; i >= 0; i--)
if (a[i] ||b[i])
printf(
"%lld\n
", ans);
return0;
}
清北學堂模擬賽d3t6 c
分析 比較神奇的一道題.要把樹變成環肯定要先變成鏈,然後把鏈給拼接成環.接下來考慮乙個腦洞大開的樹形dp 設f i 0 表示i不與父節點相連的鏈數,f i 1 表示i與父節點相連的鏈數,先考慮怎麼轉移f i 0 如果i不與父節點相連,那麼i肯定與兩個子節點相連,其它的子節點都不與父節點相連,而且要剪...
清北學堂模擬賽d3t1 a
問題描述 你是能看到第一題的friends呢。hja 怎麼快速記單詞呢?也許把單詞分類再記單詞是個不錯的選擇。何大爺給出了一種分單詞的方法,何大爺認為兩個單詞是同一類的當這兩個單詞的各個字母的個數是一樣的,如dog和god。現在何大爺給了你 個單詞,問這裡總共有多少類單詞。輸入格式 第一行乙個整數n...
清北學堂模擬賽d6t3 反擊數
分析 顯然是一道數字dp題,不過需要一些奇怪的姿勢.常規的數字dp能統計出乙個區間內滿足條件的數的個數,可是我們要求第k個,怎麼辦呢?轉化為經典的二分問題,我們二分當前數的大小,看它是第幾大的,就可以了.顯然數字dp套上模板,再用上kmp的next陣列就可以了,傳遞4個引數 還剩下多少位沒有匹配,匹...