狐进行了一次黑客马拉松大赛,全公司一共分为了N个组,每组一个房间排成一排开始比赛,比赛结束后没有公布成绩,但是每个组能够看到自己相邻的两个组里比自己成绩低的组的成绩,比赛结束之后要发奖金,以1w为单位,每个组都至少会发1w的奖金,另外,如果一个组发现自己的奖金没有高于比自己成绩低的组发的奖金,就会不满意,作为比赛的组织方,根据成绩计算出至少需要发多少奖金才能让所有的组满意。
狐进行了一次黑客马拉松大赛,全公司一共分为了N个组,每组一个房间排成一排开始比赛,比赛结束后没有公布成绩,但是每个组能够看到自己相邻的两个组里比自己成绩低的组的成绩,比赛结束之后要发奖金,以1w为单位,每个组都至少会发1w的奖金,另外,如果一个组发现自己的奖金没有高于比自己成绩低的组发的奖金,就会不满意,作为比赛的组织方,根据成绩计算出至少需要发多少奖金才能让所有的组满意。
每组数据先输入N,然后N行输入N个正整数,每个数表示每个组的比赛成绩。
输出至少需要多少w的奖金
10 20 32 12 32 45 11 21 31 41 33
20
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int n;
while(cin>>n)
{
vector<int>a(n,0);
for(int i=0;i<n;i++)
cin>>a[i];
vector<int>b(n,1);
for(int i=1;i<n;i++)//从前往后
if(a[i]>a[i-1])
b[i]=b[i-1]+1;
for(int i=n-2;i>=0;i--)//从后往前
if(a[i]>a[i+1]&&b[i]<b[i+1]+1)
b[i]=b[i+1]+1;
long sum=0;
for(int i=0;i<n;i++)
sum+=b[i];
cout<<sum<<endl;
}
}
之前做过类似的,就是从前往后来一遍,后面比前面大就++;再从后往前一遍 ,前面比后面大就++
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
int N = scanner.nextInt();
int[] grades = new int[N];
for (int i = 0; i < N; i++) {
grades[i] = scanner.nextInt();
}
int[] bonus = new int[N];
int[] cobonus = new int[N];
bonus[0] = 1;
cobonus[N-1] = 1;
for (int i = 1; i < grades.length; i++) {
if (grades[i] > grades[i-1])
bonus[i] = bonus[i-1] + 1;
else
bonus[i] = 1;
}
for (int i = N-1; i > 0; i--) {
if (grades[i-1] > grades[i])
cobonus[i-1] = cobonus[i] + 1;
else
cobonus[i-1] = 1;
}
int sum = 0;
for (int i = 0; i < N; i++) {
int temp = bonus[i]>cobonus[i]?bonus[i]:cobonus[i];
sum += temp;
}
System.out.println(sum);
}
}
}
dp[i]表示每个组的奖金 一开始都是0(每个组的1万最后加 反正总和是n万)
对每个点i往两边搜索 如果两边都i比高dp[i]=0
否则找到比i低且持续降低的最长长度len此时dp[i] = len - 1; 左右两个方向取最大的
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 1e5 + 3;
int a[maxn], dp[maxn], n;
void solve(int p){//每个点往两边搜索
int pos = p, len = 1;
while(pos+1 < n && a[pos+1] < a[pos]){//右边
pos++; len++;
}
dp[p] = len - 1, len = 1, pos = p;
while(pos-1 >= 0 && a[pos-1] < a[pos]){//左边
pos--; len++;
}
dp[p] = max(dp[p], len - 1);//取左右最大的
}
int main(){
while(scanf("%d", &n) != EOF){
for(int i = 0; i < n; i++) scanf("%d", &a[i]);
memset(dp, 0, sizeof(dp));
int ans = n;
for(int i = 0; i < n; i++) {
solve(i); ans += dp[i];
}
cout<<ans<<endl;
}
}
#include <bits/stdc++.h>
using namespace std;
int main(){
for(int N,sum;cin>>N;){
vector<int> score(N,0),bonus(N,1);
for(int i=0;i<N;cin>>score[i++]);
for(int i=1;i<N;++i){
if (score[i] > score[i-1])
bonus[i]=bonus[i-1]+1;
else if (score[i]<score[i-1]){
for(int j=i-1;j>-1;--j){
if (score[j]>score[j+1] && bonus[j]<=bonus[j+1])
++bonus[j];
else break;
}
}
}
for(int i=sum=0;i<N;sum+=bonus[i++]);
cout<<sum<<endl;
}
return 0;
}
先说下思路,一开始只是考虑到11,21,32,54,11,22这种情况的,设想的是如果遇到比前一个大的就 加一,如果遇到比前面小的就初始化为1,弄一个数组存这些数,但是如果遇到这种情况就不行了, 例如:11,21,32,54,33,22,11,这样的话,会导致答案错误。 解决办法的是弄两个数组,一个数组按照正常的顺序遍历,另一个数组倒序遍历,然后比较两个数组 的值,取较大的值即可。
import java.util.Scanner; public class SendWard { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Scanner s = new Scanner(System.in); while (s.hasNextInt()) { int n = s.nextInt(); int a[] = new int[n]; int h[] = new int[n]; h[0] = 1; int r[] = new int[n]; int res = 0; r[n - 1] = 1; for (int i = 0; i < n; i++) { a[i] = s.nextInt(); } for (int i = 1; i < n; i++) { if (a[i - 1] < a[i]) { h[i] = h[i - 1] + 1; } else { h[i] = 1; } } for (int i = n - 2; i >= 0; i--) { if (a[i] > a[i + 1]) { r[i] = r[i + 1] + 1; if (r[i] > h[i]) h[i] = r[i]; } else { r[i] = 1; } } for (int i = 0; i < n; i++) { res += h[i]; } System.out.println(res); } } }
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, const char * argv[]) {
int n;
while(cin >> n) {
int count = n;
vector<int> A;
while (count-- > 0) {
int temp;
cin >> temp;
A.push_back(temp);
}
vector<int> money(n, 1);
for (int i = 1; i < n; i++) {
if (A[i] > A[i - 1]) {
money[i] = money[i - 1] + 1;
}
}
for (int i = n - 2; i >= 0; i--) {
if (A[i] > A[i + 1] && money[i] <= money[i + 1]) {
money[i] = money[i + 1] + 1;
}
}
int sum = 0;
for (int i = 0; i < n; i++) {
sum += money[i];
}
cout << sum << endl;
}
} #include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main(){
int N;
while(cin>>N){
vector<int> array(N);
for(int i=0;i<N;i++){
cin>>array[i];
}
vector<int> bonus(N);
for(int i=0;i<N;i++) bonus[i]=1;
int money=0;
for(int i=0;i<N;i++){
if(i==0){
if(array[i]>array[i+1]){
bonus[i]=bonus[i+1]+1;
}
}else{
if(i==N-1){
if(array[i]>array[i-1]){
bonus[i]=bonus[i-1]+1;
}
}else{
if(array[i]>array[i-1]&&array[i]>array[i+1]){
bonus[i]=bonus[i-1]>bonus[i+1]? bonus[i-1]+1:bonus[i+1]+1;
}else{
if(array[i]>array[i-1]&&array[i]<=array[i+1])
bonus[i]=bonus[i-1]+1;
if(array[i]<array[i-1]&&array[i]>=array[i+1])
bonus[i]=bonus[i+1]+1;
}
}
}
money+=bonus[i];
}
int x=money;
money=0;
for(int i=N-1;i>=0;i--){
if(i==0){
if(array[i]>array[i+1]){
bonus[i]=bonus[i+1]+1;
}
}else{
if(i==N-1){
if(array[i]>array[i-1]){
bonus[i]=bonus[i-1]+1;
}
}else{
if(array[i]>array[i-1]&&array[i]>array[i+1]){
bonus[i]=bonus[i-1]>bonus[i+1]? bonus[i-1]+1:bonus[i+1]+1;
}else{
if(array[i]>array[i-1]&&array[i]<=array[i+1])
bonus[i]=bonus[i-1]+1;
if(array[i]<array[i-1]&&array[i]>=array[i+1])
bonus[i]=bonus[i+1]+1;
}
}
}
money+=bonus[i];
}
if(x<money)
cout<<money<<endl;
else
cout<<x<<endl;
}
return 0;
}
#include <iostream>
#include <vector>
using namespace std;
int main(){
int N,i,j,k;
while(cin>>N){
vector<int> vec;
int n;
for(i=0;i<N&&cin>>n;i++){
vec.push_back(n);
}
int sum=0;
i=0;
while(i<N){
k=1;
for(j=i;j<N-1&&vec[j]>vec[j+1];j++)
k++;
for(;i<=j;i++){
sum+=k;
if(i<N-1&&vec[i]>vec[i+1])
k--;
}
for(;i<N&&i>0&&vec[i-1]<vec[i];i++){
k++;
sum+=k;
}
int l=1;
for(j=i-1;j<N-1&&vec[j]>vec[j+1];j++,l++);
if(l>k)
sum=sum-k+l;
}
cout<<sum<<endl;
}
}
#include <iostream>
using namespace std;
int n;
int main(){
while(cin >> n){
int A[n];
for(int i=0; i<n; ++i) cin >> A[i];
int B[n], C[n];
for(int i=0; i<n; ++i){
if(i == 0) B[i] = 1;
else if(A[i] > A[i-1]) B[i] = B[i-1] + 1;
else if(A[i] <= A[i-1]) B[i] = 1;
}
for(int i=n-1; i>=0; --i){
if(i == n-1) C[i] = 1;
else if(A[i] > A[i+1]) C[i] = C[i+1] + 1;
else if(A[i] <= A[i+1]) C[i] = 1;
}
int res = 0;
for(int i=0; i<n; ++i){
res += max(B[i], C[i]);
}
cout << res << endl;
}
return 0;
} 正着来一遍,倒着来一遍,再来一遍取max
#include <bits/stdc++.h>
using namespace std;
int main()
{ int N; while(cin>>N) { vector<int> score; vector<int> money(N,0); for(int i=0;i<N;i++) { int t; cin>>t; score.push_back(t); } money[0] = 1; for(int i=0;i<N-1;i++) { if(score[i] < score[i+1]) money[i+1] = money[i] + 1; else if(score[i] > score[i+1]){ money[i+1] = 1; if(money[i] <= money[i+1]) { for(int k=i+1;score[k-1]>score[k]+1 && money[k]+1>money[k-1];k--) money[k-1] = money[k-1]+1; } }else money[i+1] = 1; } int sum = 0; for(int i=0;i<money.size();i++) sum += money[i]; cout<<sum<<endl; } return 0;
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace GetBonus
{
class Program
{
static void Main(string[] args)
{
int N = 0, i, j, pregrade, prebonus, sum;
//输入组数
N = Convert.ToInt32(Console.ReadLine());
while (N != 0)
{
int[] grade = new int[N];
int[] bonus = new int[N];
//依次输入分数
for (i = 0; i < N; i++)
{
grade[i] = Convert.ToInt32(Console.ReadLine());
}
//初始化第一组为1w
bonus[0] = 1;
for (i = 1; i < N; i++)
{
//初始化该组奖金为1w
bonus[i] = 1;
//得到前一组的分数,并得到前一组的奖金
pregrade = grade[(i - 1)];
prebonus = bonus[(i - 1)];
//之前一组分数比该组高但奖金不如该组此时奖金
if ((prebonus <= bonus[i]) && (pregrade > grade[i]))
{
//前一组奖金比当前组加一
bonus[(i - 1)] = bonus[i] + 1;
//之后需将前面的组依次增加奖金
for (j = i - 1; j > 0; j--)
{
if ((bonus[j - 1] <= bonus[j]) && (grade[j - 1] > grade[j]))
{
bonus[(j - 1)] = bonus[j] + 1;
}
}
}
//之前组分数比当前组低
if (pregrade < grade[i])
{
//当前组奖金比之前组多1
bonus[i] = bonus[(i - 1)] + 1;
}
}
sum = bonus.Sum();
Console.WriteLine(sum);
N = 0;
//输入下一组数
N = Convert.ToInt32(Console.ReadLine());
}
}
}
}
// n比相邻的都大 d[n] = max(d[n-1],d[n+1])+1 递推注意边界
// n小于其中一个 d[n] = d[max_index]+1
// n最小 d[n]=1
#include <vector>
#include <iostream>
using namespace std;
int dp(int n, vector<int> &cj, vector<int> &jj)
{
if(jj[n]>=0)return jj[n];
if(n==0)
{
if(cj[0]>cj[1])return dp(1,cj,jj)+1;
else return 1;
}
else if(n == cj.size()-1)
{
if(cj[n]>cj[n-1]) return dp(n-1,cj,jj)+1;
else return 1;
}
else
{
int left=n-1;
int right=n+1;
if(cj[n]<=cj[left] && cj[n]<=cj[right])return 1;
else if(cj[n]<=cj[left] && cj[n]>jj[right]) return dp(right,cj,jj)+1;
else if(cj[n]>cj[left] && cj[n]<=cj[right]) return dp(left,cj,jj)+1;
else return max(dp(left,cj,jj),dp(right,cj,jj))+1;
}
}
int main()
{
int n;
while(cin>>n)
{
vector<int> vc(n,0);
for(int i=0;i<n;i++)
cin>> vc[i];
vector<int> jj(n,-1);
int sum=0;
for(int i=0;i<n;i++)
sum+=dp(i,vc,jj);
cout<<sum<<endl;
}
return 0;
}
import java.util.*;
public class Main{
public static void main(String[]args){
Scanner ins = new Scanner(System.in);
int[] z = null;
boolean b = false;
int i = 0;
while(ins.hasNextInt()){
int temp = ins.nextInt();
if(!b){
z = new int[temp];
b = true;
continue;
}
z[i++] = temp;
if(i == z.length){
int bonusMoney = caculateBonus(z);
System.out.println(bonusMoney);
b = false;
i = 0;
}
}
}
public static int caculateBonus(int[] array){
int bonus = 1;//奖金总和
int left = 1;//左边的奖金,暂且为1,后面会做补偿
int length = array.length;
for (int i = 1; i < length; ++i) {
if (array[i] > array[i - 1]) {
left++;//升序直接+1
} else if (array[i] == array[i - 1]) {
left = 1;
}
//当遇到降序时,要特殊处理,寻找降序的最低点,最低点为1,然后从最低点倒过来依次+1
else if( array[i] < array[i - 1]){
int start = i-1 ;// 记录起点
while (i < length && array[i] < array[i - 1]) {// 寻找终点
i++;
}
//回退一步,因为最后一步多加了一次
i--;
// 此时终点是i,奖金是1,从终点返回起点依次+1
int temp = 1;
for (int j = i; j > start; --j) {
bonus += temp;
temp++;
}
// 当temp比起点大时,起点位置的奖金理应是temp(此前是left),因此我们需要加上补偿值
if (temp > left) {
bonus += (temp - left);
}
left = 1;//别忘记重新设置左边奖金为1
continue;
}
bonus += left;
}
return bonus;
}
}
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main()
{
int N;
while(cin>>N)
{
vector<int>arr(N);
for(int i=0;i<N;i++)
cin>>arr[i];
vector<int>dp(N,1);
//正向都满足条件的情况下,但是忽略了46 23 13这样的连续降的情况,所以需要反向再递推一次
dp[0]=1;
for(int i=1;i<N;i++)
{
if(arr[i]>arr[i-1])
dp[i]=dp[i-1]+1;
else if(arr[i]==arr[i-1])dp[i]=dp[i-1];
}
//反向
for(int i=N-2;i>=0;i--)
{
if(arr[i]>arr[i+1])
dp[i]=max(dp[i],dp[i+1]+1);
}
int res=0;
for(int i=0;i<N;i++)
res+=dp[i];
cout<<res<<endl;
}
return 0;
}
<?php
function init()
{
$ret = array();
while ($record = trim(fgets(STDIN)))
{
$path = explode(" ", $record)[0];
$pathArray = explode("\\", $path);
$fileName = end($pathArray);
$line = intval(explode(" ", $record)[1]);
$key = $fileName." ".$line;
if ( in_array($key, array_keys($ret)) )
{
$ret[$key] = $ret[$key] + 1;
}
else
{
$ret[$key] = 1;
}
}
return $ret;
}
//排序并返回前n条记录
function stableSort( $array, $n )
{
$values = array_values( $array );
array_multisort( $values, SORT_DESC, array_keys($values), SORT_ASC, $array);
if ( sizeof($array) <= $n)
{
return $array;
}
else
{
return array_slice($array,0, $n);
}
}
//修正key
function format( $array )
{
$ret = array();
foreach ($array as $k => $v)
{
$fileName = explode(" ", $k)[0];
if ( strlen($fileName) > 16 )
{
$fileName = substr($fileName,strlen($fileName) - 16, 16);
}
$key = $fileName." ".explode(" ", $k)[1];
$ret[ $key ] = $v;
}
return $ret;
}
function myPrint( $ret )
{
foreach ($ret as $k=>$v)
{
print $k." ".$v."\n";
}
}
function main()
{
$array = init();
$ret = stableSort( $array, 8 );
$ret = format( $ret );
myPrint($ret);
}
main();
while 1: try: N=int(input()) score=[int(input()) for i in range(N)] reverse=score[::-1]#分数反序排列 bonus1=[1 for i in range(N)]#初始值均为1 bonus2=[1 for i in range(N)] ans=[] for i in range(1,N):#后一个数大于前一个数,则+1 if score[i]>score[i-1]: bonus1[i]=bonus1[i-1]+1 if reverse[i]>reverse[i-1]: bonus2[i]=bonus2[i-1]+1 bonus2=bonus2[::-1]#反序 for i in range(N):#取两次排序中的较大值 ans.append(max(bonus1[i],bonus2[i])) print(sum(ans)) except: break
import sys
if __name__ == "__main__":
grade = []
for i in sys.stdin:
grade.append(int(i.strip('\n')))
grade_re = grade.copy()
grade_re.reverse()
re1 = []
re2 = []
for i in range(1,grade[0]+1):
if i == 1:
re1.append(1)
continue
if grade[i-1] < grade[i]:
re1.append(re1[i-2]+1)
elif grade[i-1] == grade[i]:
re1.append(re1[i-2])
else:
re1.append(1)
for i in range(0,len(grade_re)-1):
if i == 0:
re2.append(1)
continue
if grade_re[i-1] < grade_re[i]:
re2.append(re2[i-1]+1)
elif grade_re[i-1] == grade_re[i]:
re2.append(re2[i-1])
else:
re2.append(1)
re2.reverse()
res = [max(a,b) for a,b in zip(re1,re2)]
print(sum(res))
本地测试没毛病,但是在这输出为空,不知道为啥。。。
对于给定的一堆成绩,从开始往后,第一个初始化为 1W ,依次向后初始化 i +1 的 money 值,
当 i 对应的分数比 i+1 的分数小时, i+1 应该拿到更多的前,所以有 money[i+1]=money[i]+1;
当 i 对应的分数跟 i+1 相等时,反正也看不到,将 money[i+1] 设为 1 ;
当 i 对应的分数比 i +1 大时: money[i+1] 应该是此时较小的,将其设为 1 ,但是可能后面的跟他相同或比他小,因此要将后面分数递增的那些 money 跟新一下,此处采用一个 for 循环,循环从 k=i+1 开始,当 score[k-1]>score[k]&&money[k]+1>money[k-1] 时才 -- ,注意与后面的条件,是为了判断 money 值可能的断崖式下降(因为起始 money[i+1] 设为 1 了,可能比 money[i] 小很多)。满足条件将其值加 1.