使用优先队列即可,身高小的优先,从左到右每当有人进入队列时,所有低于这个人身高的人看向的人就是这个人,把这些人出队列,记录下来就可以了。
#include<stdio.h>
#include<iostream>
#include<map>
#include<vector>
#include<algorithm>
#include<queue>
#define MAX 100005
#define INF 0x3f3f3f3f
using namespace std;
struct node{
int val;
int id;
}t[MAX];
struct cmp{
bool operator()(node a,node b){
return a.val>b.val;
}
};
priority_queue<node,vector<node>,cmp > q;
int res[MAX];
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&t[i].val);
t[i].id=i;
}
for(int i=1;i<=n;i++){
q.push(t[i]);
if(!q.empty()){
while(q.top().val<t[i].val){
int id=q.top().id;
q.pop();
res[id]=i;
}
}
}
for(int i=1;i<=n;i++){
printf("%d\n",res[i]);
}
return 0;
}
数位dp,将字符串看成26进制的数,然后dfs+记忆化搜索。
时间复杂度:O(n * 26 * 26)
#include<stdio.h>
#include<iostream>
#include<map>
#include<vector>
#include<algorithm>
#include<queue>
#include<string.h>
#define MAX 1005
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
ll mod=1e9+7,num=26*26*26;
ll dp[MAX][30][30];
int n,t;
ll dfs(int pos,int c1,int c2){
if(pos==0) return 1;
if(dp[pos][c1][c2]!=-1) return dp[pos][c1][c2];
ll ans=0;
for(int i=1;i<=26;i++){
if(c1=='L'-'A'+1&&c2=='O'-'A'+1&&i=='L'-'A'+1) continue;
ans=(ans+dfs(pos-1,c2,i))%mod;
}
dp[pos][c1][c2]=ans;
return ans;
}
ll f(ll x){
int pos=x;
return dfs(pos,0,0);
}
int main(){
memset(dp,-1,sizeof(dp));
while(scanf("%d",&t)!=EOF){
while(t--){
scanf("%d",&n);
printf("%lld\n",f(n));
}
}
return 0;
}
思路是贪心+排序。选取中位数是最好的选择方案。
我们可以选取行的中位数,把企鹅都移动到这一行,或者选取列的中位数,把企鹅都移动到这一列。
#include <iostream>
#include <stdio.h>
#include <queue>
#include <set>
#include <string>
#include <map>
#include <cmath>
#include <algorithm>
#include <cstring>
#define MAX 600005
typedef long long ll;
using namespace std;
int x[MAX], y[MAX];
int main(){
int n;
scanf("%d",&n);
for (int i=1;i<=n;i++){
scanf("%d%d",&x[i],&y[i]);
}
sort(x+1,x+n+1);
sort(y+1,y+n+1);
ll ansx1=0,ansy1=0,ansx=0,ansy=0;
ll mid=n/2+1;
//如果移动到同一行
for(int i=1;i<=n;i++){
ansy+=abs(y[i]-y[mid]);
}
//如果移动到同一列
for(int i=1;i<=n;i++){
ansx+=abs(x[i]-x[mid]);
}
for(int i=1;i<=n;i++){ //转移需要的步数
ansx1+=abs(i-x[i]);
ansy1+=abs(i-y[i]);
}
ll ans=min(ansx1+ansy,ansy1+ansx);
printf("%lld\n",ans);
return 0;
}
原文:https://www.cnblogs.com/zzh1582188532/p/12354276.html