1. 程式人生 > >Codeforces 777C - Alyona and Spreadsheet - [DP]

Codeforces 777C - Alyona and Spreadsheet - [DP]

cout 長度 const int ace names nbsp 是否 problems

題目鏈接:http://codeforces.com/problemset/problem/777/C

題意:

給定 $n \times m$ 的一個數字表格,給定 $k$ 次查詢,要你回答是否存在某一列 $j$,其對應於詢問區間 $[l,r]$ 的 $a[l][j], a[l+1][j], \cdots, a[r][j]$ 這個序列,是否為非遞減的。

題解:

考慮 $f[i][j]$ 表示只考慮第 $j$ 列的情況下,以 $a[i][j]$ 為末尾的單調不減序列的最長長度,這個很容易求出來。

那麽,我們對於某一行 $i$,已經可以知道 $f[i][1],f[i][2], \cdots, f[i][m]$ 這些值了,求出它們的最大值 $mx[i]$,這個值即對應一個查詢 $[l,r]$,在確定下端為 $r$ 的情況下,其上端最長可以延伸多遠。

時間復雜度為 $O(nm+k)$。

AC代碼:

#include<bits/stdc++.h>
using namespace std;
const int SIZE=1e5+5;
int n,m,q;
int a[SIZE],f[SIZE],mx[SIZE];
inline idx(int x,int y){return x*m+y;}
inline x(int idx){return idx/m;}
inline y(int idx){return idx%m;}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(
0), cout.tie(0); cin>>n>>m; for(int i=0;i<n;i++) { mx[i]=1; for(int j=0;j<m;j++) { cin>>a[idx(i,j)]; if(i==0 || a[idx(i-1,j)]>a[idx(i,j)]) f[idx(i,j)]=1; else f[idx(i,j)]=f[idx(i-1,j)]+1; mx[i]
=max(mx[i],f[idx(i,j)]); } } cin>>q; int l,r; while(q--) { cin>>l>>r; l--,r--; if(mx[r]>=r-l+1) cout<<"Yes\n"; else cout<<"No\n"; } }

Codeforces 777C - Alyona and Spreadsheet - [DP]