2017年院赛C题 treat

来源:互联网 发布:网络客户服务的优势有 编辑:程序博客网 时间:2024/06/06 18:19

目录:

2017年院赛A题 Neptune'Pudding

2017年院赛B题 N个数求和

2017年院赛C题 treat

2017年院赛D题 简单加密

2017年院赛E题 守望者的逃离

2017年院赛F题 数独游戏

2017年院赛G题 忠诚

2017年院赛H题 最大异或和


题目:

描述

给出长度为N的数列{A_i},每次可以从最左边或者最右边取走一个数,第i次取数得到的价值是i*A_j。求价值之和最大的取数方案。

输入格式

第一行,一个整数,表示数列长度N。
接下来N行,每行一个整数,表示数列A_i。

N<=2000,A_i<=1000

输出格式

一个整数,表示最大的价值之和。

测试样例1

输入

5
1
3
1
5
2

输出

43


标程:

#include <stdio.h>#include <string.h>#include <iostream>using namespace std;int a[2005] , dp[2005][2005];int main(){    int n;    scanf("%d" , &n);    for(int i=1 ; i<=n ; i++){        scanf("%d" , a+i);    }    dp[0][1] = a[n] , dp[1][0] = a[1];    int ans = 0;    for(int i=1 ; i<=n ; i++){        for(int j=1 ; j<=n ; j++){            if(i+j>n) break;            dp[i][j] = max(dp[i-1][j]+(i+j)*a[i] , dp[i][j-1]+(i+j)*a[n-j+1]);            if(i+j == n) ans = max(ans , dp[i][j]);        }    }    printf("%d\n" , ans);    return 0;}

我的代码:

#include<iostream>using namespace std;int n,list[2000],ans[2000][2000];int f(int low,int high){if(ans[low][high]>=0)return ans[low][high];if(low==high)return list[low]*n;int a=f(low,high-1)+list[high]*(n-high+low);ans[low][high]=f(low+1,high)+list[low]*(n-high+low);if(ans[low][high]<a)ans[low][high]=a;return ans[low][high];}int main(){cin>>n;for(int i=0;i<n;i++)cin>>list[i];for(int i=0;i<n;i++)for(int j=i;j<n;j++)ans[i][j]=-1;cout<<f(0,n-1);return 0;}

0 0