可能是几年被石油大折磨的缘故,来刷刷题,遇到了一个看起来很少人过的题(3个人),然后尝试了一下。
题意很简单,给你
n
n
n个数,在
n
−
1
n-1
n−1个空隙里选择加号和乘号,可以形成括号,然后使得结果最大。
首先一看,妥妥的思维题,然后我刚开始想了一个dp的思路,首先我们想一个简单的 O ( n 2 ) O(n^2) O(n2)dp , 首先我们可以选择连续是一段加上,所以我们得到一个方程式。
f [ i ] = m a x ( f [ j ] ∗ ( s [ i ] − s [ j − 1 ] ) ) f[i] = max(f[j] * (s[i] - s[j - 1])) f[i]=max(f[j]∗(s[i]−s[j−1]))
然后开始写代码
放一下 O ( n 2 ) O(n^2) O(n2)的代码
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>
#include <queue>
#define x first
#define y second
using namespace std;
const int N = 1e5 + 10 ;
const int M = 2 * N ;
const int Inf = 1e9 + 10 ;
const int mod = 10086 ;
typedef pair<int , int> PII ;
int read(){
int res = 0 , flag = 1 ;
char c = getchar() ;
while(!isdigit(c)){
if(c == '-') flag = -1 ;
c = getchar() ;
}
while(isdigit(c)){
res = (res << 1) + (res << 3) + (c ^ 48) ;
c = getchar() ;
}
return res * flag ;
}
int a[N] ;
int f[N] ;
int main(void){
int n ;
while(~scanf("%d" , &n)){
for(int i = 1 ; i <= n ; i ++) a[i] = read() ;
f[0] = 1 ;
for(int i = 1 ; i <= n ; i ++) f[i] = -Inf ;
for(int i = 1 ; i <= n ; i ++){
int ans = 0 ;
for(int j = i ; j ; j --){
ans = (ans + a[j]) % mod ;
f[i] = max(1ll * f[i] , f[j - 1] * 1ll * ans % mod) ;
}
}
printf("%d\n" , f[n]) ;
}
}
结果不出意外得了50分后wa了,后来仔细分析题目,发现因为加了模数不能判断大小,然后我就往贪心去想。
我觉得首先我们需要一个贪心,一定要多乘,并且要乘以一个大于1的数,每个乘数都是大于而且尽可能的多,于是一个贪心出来了,我们如果当前这个数是1,就加上后面的数再乘,如果大于1,直接乘以这个数就可以。
没想到以一个简单的贪心收尾。
AC代码
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>
#include <queue>
#define x first
#define y second
using namespace std;
const int N = 1e5 + 10 ;
const int M = 2 * N ;
const int Inf = 1e9 + 10 ;
const int mod = 10086 ;
typedef pair<int , int> PII ;
int read(){
int res = 0 , flag = 1 ;
char c = getchar() ;
while(!isdigit(c)){
if(c == '-') flag = -1 ;
c = getchar() ;
}
while(isdigit(c)){
res = (res << 1) + (res << 3) + (c ^ 48) ;
c = getchar() ;
}
return res * flag ;
}
int a[N] ;
int f[N] ;
int main(void){
int n ;
while(~scanf("%d" , &n)){
for(int i = 1 ; i <= n ; i ++) a[i] = read() ;
int ans = 1 ;
for(int i = 1 ; i <= n ; i ++){
int tot = a[i] ;
if(tot == 1){
if(i < n) tot += a[i + 1] , i ++ , ans = ans * 1ll * tot % mod ;
else ans += tot ;
}
else
ans = ans * 1ll * tot % mod ;
}
printf("%d\n" , ans) ;
}
}