UVA12983 The Battle of Chibi
Posted hs-black
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA12983 The Battle of Chibi相关的知识,希望对你有一定的参考价值。
第一眼能看出来是个dp
O($n^3$) 暴力应该很好想 dp[i][j] = $\sum_k=1^i [a[k] < a[i]] *dp[k][j-1]$
发现dp[i][j] 为前面小于它的数长度为j-1的总和, 用树状数组前缀和优化一下搞成$O(n^2log_n)$
先离散化, dp时先枚举位置,再枚举上升序列的长度
树状数组要开二维哦, 打代码的时候发现dp数组可以用树状数组直接代替(小小的空间优化)
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1005;
const int P = 1e9+7;
int read(void)
int x = 0;
char c = getchar();
while (!isdigit(c)) c = getchar();
while (isdigit(c))
x = (x << 3) + (x << 1) + c - '0';
c = getchar();
return x;
int T, n, m;
int a[N];
struct node
int pos, val;
bool operator < (const node &i) const
if (val == i.val) return pos < i.pos;
return val < i.val;
p[N];
bool cmp(node i,node j)
return i.pos < j.pos;
long long d[N][N];
inline int low(int x)
return x & -x;
int sum(int x,int p)
long long val = 0;
for (;x;x -= low(x)) val += d[p][x];
return val % P;
void add(int x,int k,int p)
for (;x <= n; x += low(x)) d[p][x] = (d[p][x] + k) % P;
int main()
T = read();
int cnt = 0;
while (T--)
cnt++;
n = read(), m = read();
for (int i = 1;i <= n; i++) p[i] = (node)i,read();
sort(p + 1,p + n + 1);
int x = 0, k = 0;
for (int i = 1;i <= n; i++)
if (x == p[i].val)
p[i].val = k;
else
x = p[i].val;
p[i].val = i;
k = i;
sort(p + 1,p + n + 1, cmp);
memset(d, 0, sizeof(d));
long long ans = 0;
for (int i = 1;i <= n; i++)
add(p[i].val, 1, 1);
for (int j = 2;j <= m; j++)
int k = sum(p[i].val-1, j-1);
add(p[i].val, k, j);
if (j == m) ans = (ans + k) % P;
if (m == 1) ans += n;
printf ("Case #%d: %lld\n", cnt, ans % P);
return 0;
以上是关于UVA12983 The Battle of Chibi的主要内容,如果未能解决你的问题,请参考以下文章
luogu UVA12983ybtoj例题3树状数组严格上升子序列数&The Battle of Chibi
HDU - 5542 The Battle of Chibi(LIS+树状数组优化)