链接:https://ac.nowcoder.com/acm/contest/642/I
来源:牛客网
题目描述
19 年校赛的结果已经出炉,为了对大家的积极参与表示感谢,杨主席准备拿出他的工资给大家发福利。
所有参赛选手排成一排,每位同学都对于有一个量化的得分(当然,得分越高越好)。杨主席已事先知道选手们的排队顺序以及个人的得分,他将一个一个给大家发糖。
杨主席是个有原则的男人,但他原则也是有限的。所谓有原则是指:分数高的一定比分数低的能拿到更多的糖果且分数 一样的拿到的糖果一样多;所谓原则是有限的又是指:刚刚说的原则仅对排队中相邻的两人生效,且允许有人拿不到糖果(杨主席是个穷逼)。
杨主席并不想多花一分钱买额外的糖,于是他想知道在各种情况下最少需要购入几块糖。
输入描述:
首先是一个整数T,表示数据输入的组数,T<=20。 对于每组数据,有两行: (1)一个整数n,表示队列中的人数,0 < n <= 1000。 (2)n个整数a[0] ... a[n-1],表示按队列顺序每个人的得分,注意可能会有同分的情况,保证a[i]是int类型的。
输出描述:
对应T行,每行即对应每组输入的最少购入糖数结果。
示例1
输入
复制
2 6 12 13 14 5 10 13 6 2 2 2 2 2 2
输出
复制
6 0
题解:每个位置向比他大的建一条权值为1的边,相等的建权值为0的边,按每个位置的值从小到大跑一边,每次取个最大值即可
#include<bits/stdc++.h>
using namespace std;
int n;
vector<pair<int,int> > v[1010];
struct node{
int id,val;
bool operator <(const node &xx)const
{
return val<xx.val;
}
}b[1010];
int a[1010];
int in[1010];
int dp[1010];
void add(int x,int y,int z)
{
v[x].push_back(make_pair(y,z));
in[y]++;
}
void dfs(int u,int fa)
{
int l=v[u].size(),to;
for(int i=0;i<l;i++)
{
to=v[u][i].first;
if(to==fa) continue;
dp[to]=max(dp[to],dp[u]+v[u][i].second);
dfs(to,u);
}
}
int main()
{
int T;
cin>>T;
while(T--)
{
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i],v[i].clear(),in[i]=0,dp[i]=0,b[i].id=i,b[i].val=a[i];
if(n==1)
{
printf("0\n");continue;
}
for(int i=1;i<n;i++)
{
if(a[i]>a[i+1]) add(i+1,i,1);
if(a[i]==a[i+1]) add(i,i+1,0),add(i+1,i,0);
if(a[i]<a[i+1]) add(i,i+1,1);
}
sort(b+1,b+1+n);
for(int i=1;i<=n;i++)
{
dfs(b[i].id,0);
}
int ans=0;
for(int i=1;i<=n;i++)ans+=dp[i];
printf("%d\n",ans);
}
return 0;
}