2021icpc昆明站热身赛

B:Rounds

链接:https://ac.nowcoder.com/acm/contest/13977/B
来源:牛客网

The popular PefectSharp online group gathers fans of workouts and healthy lifestyle all over the world. Every group member has managed to gain a certain amount of credits for the trendy MV03 online sports platform, giving them access to various workout and relaxation resources.
The amount of credits owned may however largely differ from one person to the other. Since PefectSharp members value sharing and solidarity, they decide to redispatch credits by playing the following game:
The N group members are numbered from 1 to N and the game comprises k rounds, for some integer k such that 1 \leq k \leq N1≤k≤N. During the i-th round of the game, all members except member i give S credits to member i. The game may end after any round, and its outcome will be the minimum amount of credits held by a member of the group after that round.
Your task is to figure out the maximum possible game outcome, across all possible game endings.

输入描述:
The first line of the input contains two integers N and S.
Each of the N following lines contains a single integer, the (i + 1)-th line containing the amount of credits Ciinitially owned by member i.
输出描述:
The output should contain a single integer value C corresponding to the maximum possible game outcome.
示例1
输入
复制
3 10
24
42
38
输出
复制
28
说明
The game proceeds as follows:
After round 1 the amounts of credits held are 44, 32, 28 and the minimum is 28.
After round 2 the amounts of credits held are 34, 52, 18 and the minimum is 18.
After round 3 the amounts of credits held are 24, 42, 38 and the minimum is 24.
The best possible outcome is therefore 28, which corresponds to ending the game after round 1.

备注:
1\leq N \leq 100,0001≤N≤100000
1\leq S \leq 100,000,0001≤S≤100000000

主要思路:
不能暴力,两层循环一定会超时
想办法省略内层循环

方法一:
利用小根堆,如果最小的那个是轮数前边的位置,则要+ns,并且标记他已经加过,如果是后边直接-轮数s与ans比较,取最大值

#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
struct node
{
    ll x,num;
};
priority_queue<node> a;
bool book[1000001];
bool operator < (node a,node b)
{
    return a.x>b.x ;//将<重载为>实现小根堆
}
int  main()
{
	int  n,s;
    cin>>n>>s;
    for(int i=1;i<=n;i++)
    {
        int x;
        cin>>x;
        a.push({x,i});
    }
    ll ans=0;
    for(int i=1;i<=n;i++)
    {
        while(a.top().num<=i&&book[a.top().num]==0)
        {
            ll nnum=a.top().num;
            ll x=a.top().x+s*n;
            a.pop();
            a.push({x,nnum});
            book[nnum]=1;
        }
        ans=max(ans,a.top().x-i*s);
    }
    cout<<ans<<endl;
	return 0;
}

直接找规律:

#include
#define ll long long
using namespace std;
const int maxn=2e5+5;
ll a[maxn],b[maxn];
ll aa[maxn];
int main()
{
    ll n,s;
    cin>>n>>s;
    a[0]=0x3f3f3f3f,b[n+1]=0x3f3f3f3f;
    for(int i=1;i<=n;i++){
        cin>>aa[i];
    }
    for(int i=1;i<=n;i++){
        a[i]=min(a[i-1],aa[i]);//a存<=轮数中最小的
    }
    for(int i=n;i>=1;i--){
        b[i]=min(b[i+1],aa[i]);//b存>轮数中最小的
    }
    ll ans=-1;
    //分将两类讨论,因为第n轮时第n个不存在b
    for(int i=1;i<n;i++){
        ans=max(ans,min(a[i]+s*(n-i),b[i+1]-s*i));
    }
    ans=max(ans,a[n]);
    cout<<ans;
    return 0;
}

C:Statues

链接:https://ac.nowcoder.com/acm/contest/13977/C?&headNav=acm
来源:牛客网

To escape the loneliness of working remotely everyday, Erika decided to try on a new hobby:
sculpture. She already has a large collection of statues and the municipality has allowed her to show
her art outside.
Erika wants her statues to be well visible and thus each statue needs to be placed under a distinct
street light. Further, the arrangement should be aesthetic which means that the statues should be
placed by increasing size with the smallest statues near the beginning of the street and the biggest ones
near the end.
Erika placed her statues but she forgot to place them in increasing size and now she has to reposition
them in accordance to both of her desires.
The street has N evenly spaced street lights numbered from 1 at the beginning of the street to N at
the end of the street. You estimate the time required to move a statue of size s from the street light i
to the light j as taking Erika s × |i − j| units of time. You ask yourself, how much time does it take
to reposition all statues knowing that she will use the fastest way possible? Note that she may put
statues under street lights that do not have statues at the moment.

输入描述:
The first line of the input contains two space-separated integers: N the number of street lights and K
the number of statues. The K following lines each contains two space-separated integers, the i + 1-th
line containing the integers Pi and Si describing the i-th statue. Pi gives the number of the street light
under which the statue is and Si gives its size.
输出描述:
The output should contain a single line containing a single integer: the minimum amount of time
needed to move statues such that each statue is under a different street light and such that the size of
statues grows with the street light numbers under which they are.
示例1
输入
复制
3 3
1 3
2 2
3 1
输出
复制
8
说明
Because there are as many street lights as there are statues we needto position the statue of size 1 at street light 1 (which takes 1\times |3-1=2|1×∣3−1=2∣units of times), leave the statue of size 2 atstreet light 2, and move the statue of size 3 to the street light 3(which takes 3
\times |1-3|=63×∣1−3∣=6units of times). In total this takes 88units of time.
示例2
输入
复制
4 3
2 2
3 2
4 1
输出
3
说明
The fastest way of fixing the ordering of statues is to move
the statue of size 1 to the street light 1 for a total time of 1\times
|4-1|=31×∣4−1∣=3.

主要思路:
数据最大为5000,可以想到dp
主要要考虑雕像可以松散排列的
放已经i个雕像放在j灯下边的状态转移方程
dp[i][j]=min(dp[i][j-1],dp[i-1][j-1]+重量*距离);
即从该个灯下放雕塑和不放雕塑中选择最小的
放了i个雕像走过了j个灯的最小时间花费

#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
pair<ll,ll> q[5005];
ll dp[5005][5005];
int  main()
{
	ll n,m;
    cin>>n>>m;
    for(int i=1;i<=m;i++)
        cin>>q[i].second>>q[i].first;
    sort(q+1,q+m+1);
    for(int i=1;i<=m;i++)
    {
        dp[i][i-1]=5e18;//防止两个雕塑放重
        for(int j=i;j<=n;j++)
        {
            dp[i][j]=min(dp[i][j-1],dp[i-1][j-1]+q[i].first*1ll*abs(j-q[i].second));
        }
    }
    cout<<dp[m][n]<<endl;
	return 0;
}

你可能感兴趣的:(2021icpc昆明站热身赛)