5月19日省中提高組題解

2021-08-20 06:39:51 字數 2892 閱讀 8323

【problem a】 square

【題意】

給乙個n * n的01矩陣,要求乙個最大的全1正方形子矩陣,輸出它的面積

n <= 1000

【題解】

樸素的做法是先求二維字首和,然後暴力找最大的正方形子矩陣,時間複雜度 : o(n^3) 期望得分 : 80

考慮優化,我們發現如果有邊長為n的正方形,就一定有邊長為(n - 1)的正方形,因此,可以先二分邊長d,然後

判斷邊長為d的正方形是否存在. 時間複雜度 : o(n^2log(n)) 期望得分 : 100

【**】

#includeusing namespace std;

#define maxn 2050

int i,j,l,r,mid,n,ans;

int s[maxn][maxn];

char ch;

bool check(int d)

} return false;

}int main()

getchar();

} l = 1; r = n;

while (l <= r)

else r = mid - 1;

} printf("%d\n",ans*ans);

return 0;

}

【problem b】 findmax

【題意】

乙個包含n個元素的陣列,元素的值在1-k之間,存在多少個不同的陣列,使得掃瞄這個陣列,最大值更新了p次

【題解】

暴力搜尋,期望得分 : 30

由於t最大10^5,所以,我們不可能每次詢問都計算一次答案,因此,我們應該進行一些預處理

考慮動態規劃預處理

f[i][j][k]表示選了i個元素,元素的最大值為j,進行了k次更新的合法方案

那麼,有f[i][j][k] = f[i-1][j][k] * j + f[i-1][t][k-1] (1 <= t <= j - 1) 

這個狀態轉移方程的意思是 :

如果選到第i個元素時最大值未發生變化,那麼,就相當於前i-1個元素最大值為 j,進行了k次更新,而第i個元素就可                  以選1..j中的任何乙個數,方案數為f[i-1][j][k] * j

如果選到第i個元素時最大值發生了變化,那麼,前i-1個元素,最大值可以是1..j-1中的任何乙個數,進行了k-1次更                    新, 第i個元素為j,方案數為f[i-1][t][k-1] (1 <= t <= j - 1)

然而,這樣演算法的時間複雜度是o(nk^2p),不能通過此題

考慮優化,我們用sum[i][j][k]表示選了i-1個元素,進行j次更新,元素的最大值為1..k的方案數(字首和),

式子就被簡化為了 : f[i][j][k] = f[i-1][j][k] * j + sum[i-1][k-1][j-1]

那麼,這樣時間複雜度就被優化為了o(nkp)

對於每次詢問,答案就是sigma(f[n][i][p])(1 <= i <= k)

總時間複雜度 : o(nkp + tk) 期望得分 : 100

【**】

#includeusing namespace std;

#define maxn 101

#define maxk 301

#define maxp 101

const long long mod = 1e9 + 7;

long long i,j,k,ans,n,p,t;

long long f[maxn+10][maxk+10][maxp+10],sum[maxn+10][maxp+10][maxk+10];

int main()

for (i = 2; i <= maxn; i++)

}for (j = 0; j <= maxp; j++)

} }

while (t--)

return 0;

}

【problem c】bds

【題意】

寫出1..n的排列a,每次相鄰兩個數相加,構成新的序列,再對新序列再次進行這樣的操作,知道剩下乙個數n

給定n,要求字典序排列最小的a

【題解】

呼叫algorithm庫里的next_permutation函式,判斷是否可以得到n 期望得分 : 20

我們發現,n = c(n,1)a1 + c(n,2)a2 + c(n,3)a3 + c(n,4)a4 + ... + c(n,n)an

因此,可以通過楊輝三角計算c(n,i),然後深度優先搜尋dfs

時間複雜度 o (能過) 期望得分 : 100

【**】

#includeusing namespace std;

#define maxn 25

int i,j,n,sum,l;

int c[maxn][maxn],visited[maxn],ans[maxn];

bool solved = false;

inline void dfs(int dep,int s)

for (i = 1; i <= n; i++) }

} int main()

} dfs(1,0);

for (i = 1; i < n; i++) printf("%d ",ans[i]);

printf("%d\n",ans[n]);

return 0;

}

【總結】

總分20 + 100 + 100 = 220,第一題失分原因是因為將正方形看成了長方形,這樣的錯誤很不應該,以後

一定要避免!

這次考試,基礎演算法佔了很大比重,雖然最近一直在研究比較複雜的演算法,但是,也不能忽視了基礎演算法的

重要性!

JZOJ8月5日提高組反思

再次炸了 雖然不是爆0 但也沒差多少 想的dp 然後就打了 一開始是只能拿60的 後來想到了用字首和優化 然後打完交了 最後一分鐘測了一下空間 爆了就趕緊把陣列開小交上去 40估計用個滾動就過了 覺得那個式子特別麻煩 而且很有可能會卡精度 所以我就嘗試著去把式子化簡 化簡之後就沒有除法了 想著用線段...

紀中訓練5月6日提高組反思

又一場比賽啦啦啦 20,25th 真的是蒟蒻呀 又是租奶牛又是賣牛奶,乙個大寫的服 greedy萬歲!貪心,列舉前i頭產量最多的奶牛去賣牛奶,剩下的去租 至於考試時沒有滿分嘛,原因是我輸出時調成了 d 其實還有排序打錯 十年oi一場空,不開longlong見祖宗 靈性的暴力 儘管我考試時沒做出 選擇...

紀中訓練5月30日提高組反思

t2 usaco 2017 december gold haybale feast t3 usaco 2017 december gold a pie for a pie 120,17th 傳送門 想到了用暴力,然後線段樹求最小值 雖然a了,但我發現一堆巨佬直接暴力過 渣渣反思 多多思考 題解 傳送...