[CF777C] Alyona and Spreadsheet(dp)

题目链接:http://codeforces.com/contest/777/problem/C

预处理出LIS的值,每次更新LIS的时候,假设符合条件则f(i,j)=f(i-1,j)+1,这个时候额外记录一个dp(i),代表到第i行时前面最远到哪里。

更新dp(i)=min(dp(i), i-f(i,j)+1)即可。反过来记录i行后最远就不行,因为有可能更新不到。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef pair<int, int> pii;
 5 const int maxn = 100100;
 6 int n, m, q, l, r;
 7 vector<vector<int>> a, f;
 8 int dp[maxn];
 9 
10 signed main() {
11     // freopen("in", "r", stdin);
12     while(~scanf("%d%d",&n,&m)) {
13         a.clear(); f.clear();
14         memset(dp, 0x7f, sizeof(dp));
15         a = vector<vector<int>>(n+1);
16         f = vector<vector<int>>(n+1);
17         for(int i = 0; i <= n; i++) {
18             a[i] = vector<int>(m+1);
19             f[i] = vector<int>(m+1);
20         }
21         for(int i = 1; i <= n; i++) {
22             dp[i] = i;
23             for(int j = 1; j <= m; j++) {
24                 scanf("%d", &a[i][j]);
25             }
26         }
27         for(int j = 1; j <= m; j++) {
28             f[1][j] = 1;
29             for(int i = 2; i <= n; i++) {
30                 if(a[i][j] >= a[i-1][j]) {
31                     f[i][j] = f[i-1][j] + 1;
32                     dp[i] = min(dp[i], i-f[i][j]+1);
33                 }
34                 else f[i][j] = 1;
35             }
36         }
37         scanf("%d", &q);
38         while(q--) {
39             scanf("%d%d",&l,&r);
40             if(dp[r] <= l) puts("Yes");
41             else puts("No");
42         }
43     }
44     return 0;
45 }
原文地址:https://www.cnblogs.com/kirai/p/7252313.html