链接
https://codeforces.com/problemset/problem/1677/A
题目
思路
这题感觉还是挺有难度的(为啥题解都说不难Orz),给我启发最大的是这句话:具体怎么处理呢?把i按照n->1的顺序遍历,然后j从反方向遍历:i+1->n。求S[i][j]时用S[i+1][j],因为S对应的是以j为结尾的,然后在遍历中相当于不知道i的位置,已有的只有i+1,所以如果a[j]>a[i],那么有S[i][j] = S[i+1][j] + 1,因为多收了一个i位置的数,所以计数器加1。对L的计算同理。
同时我为了加深印象,增加了一个转向的版本。后续可以补充树状数组版的。
这相当于是dp预处理版求解。
代码
修改代码
for (int i = 1; i <= n; i++)
{
for (int j = i - 1; j >= 1; j--)
{
if (lst[j] > lst[i])
{
S[j][i] = S[j + 1][i];
L[j][i] = L[j][i - 1] + 1;
}
else
{
S[j][i] = S[j + 1][i] + 1;
L[j][i] = L[j][i - 1];
}
}
}
完整代码
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<vector>
#include<algorithm>
#include<math.h>
#include<sstream>
#include<string>
#include<string.h>
#include<iomanip>
#include<stdlib.h>
#include<map>
#include<queue>
#include<limits.h>
#include<climits>
#include<fstream>
#include<stack>
#define IOS ios::sync_with_stdio(false), cin.tie(0) ,cout.tie(0)
using namespace std;
typedef long long ll;
const int N = 5e3 + 10;
short int S[N][N], L[N][N];
int lst[N];
signed main()
{
IOS;
int t; cin >> t;
while (t--)
{
int n; cin >> n;
ll ans = 0;
for (int i = 1; i <= n; i++)cin >> lst[i];
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
S[i][j] = L[i][j] = 0;
for (int i = 1; i <= n; i++)
{
for (int j = i - 1; j >= 1; j--)
{
if (lst[j] > lst[i])
{
S[j][i] = S[j + 1][i];
L[j][i] = L[j][i - 1] + 1;
}
else
{
S[j][i] = S[j + 1][i] + 1;
L[j][i] = L[j][i - 1];
}
}
}
/*for (int i = n; i >= 1; i--)
{
for (int j = i + 1; j <= n; j++)
{
if (lst[j] > lst[i])
{
S[i][j] = S[i + 1][j] + 1;
L[i][j] = L[i][j - 1];
}
else
{
S[i][j] = S[i + 1][j];
L[i][j] = L[i][j - 1] +1;
}
}
}*/
for (int b = 2; b < n - 1; b++)
{
for (int c = b + 1; c < n; c++)
{
ans += (ll)(S[1][c] - S[b][c]) * (ll)(L[b][n] - L[b][c]);
}
}
cout << ans << '\n';
}
return 0;
}
标签:int,ll,Tokitsukaze,lst,Strange,--,include,dp
From: https://www.cnblogs.com/zzzsacmblog/p/18314354