题目及数据:http://pan.baidu.com/s/1jGBoL4U

 

第一题:

由于整个数列必须是波动的,那么这个数列只有两种形态

   o        o      o           

o     o        o

 

o     o      o

   o      o    o

这两种dp基本上没有区别,总的都可以写为dp[i][j]=max{dp[i-1][k]+w[i][j]} (k随j以及形态变化)

不过坑人的是 由于数列是环,所以首位必须也满足波动的性质。

当时是把第一位移到了n+1位,然后dp[n+1]-dp[1]的。。不过TMD好像没有任何区别T_T

所以只需要考虑第一位填什么,后面直接dp就行

 

第二题

 对于第i个跳转器,记g[i]=i+a[i],它可以跳的范围是[1,g[i]],那么这个跳转器的唯一价值就应该是g[i]。

考虑当前需要k步才能跳到终点的跳转器有{ai|a1,a2,a3,am}(a1<a2<a3<...<am) 那么这个集合唯一有价值的也只有a1(最小)

那么记录下K步的最小值Min之后,在做第k+1步的时候,只要把还没踢出去的跳转器中>=Min的构成一个集合,再取最小值即可。

那么问题来了,蓝色部分显然需要数据结构来维护,Set、Splay都可以。。考场上写set,

不过妈蛋的是,对于set<pair<int,int>>的cmp。。我写的是first<first||first==frist&&second<second

不知道有什么问题? 就是错了。。 T_T

但是分析到这。。如果稍微再多想想,

就会发现对于每个k步可以跳完的集合X_k,以及k+1步跳完的集合X_k+1,

不难发现X_k的最小值>X_k+1的最大值,那么就好办了。。O(nlogn)排序之后从后往前一次扫描即可。

 1 #include<set>
 2 #include<queue>
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<iostream>
 7 #include<algorithm>
 8 using namespace std;
 9 const int N = 100010;
10 #define For(i,n) for(int i=1;i<=n;i++)
11 #define Rep(i,l,r) for(int i=l;i<=r;i++)
12 
13 int n,W[N][4];
14 long long ans,dp[N][4];
15 
16 void read(int &v){
17     char ch=getchar();
18     while(ch>'9'||ch<'0') ch=getchar();
19     int num=0;
20     while(ch>='0'&&ch<='9'){
21         num=num*10+ch-'0';
22         ch=getchar();
23     }
24     v=num;
25 }
26 
27 void Dp1(int equal,int state){
28     memset(dp,0,sizeof(dp));
29     dp[1][state]=W[1][state];
30     Rep(i,2,n){
31         if(i%2==equal)
32           For(j,2)
33             Rep(k,j+1,3)
34               dp[i][j]=max(dp[i][j],dp[i-1][k]+W[i][j]);
35         else
36           Rep(j,2,3)
37             For(k,j-1)
38               dp[i][j]=max(dp[i][j],dp[i-1][k]+W[i][j]);
39     }               
40     if(state==2) ans=max(ans,dp[n][3]);
41     else         ans=max(max(dp[n][3],dp[n][2]),ans);
42 }
43 
44 void Dp2(int equal,int state){
45     memset(dp,0,sizeof(dp));
46     dp[1][state]=W[1][state];
47     Rep(i,2,n){
48         if(i%2==0)
49           For(j,2)
50             Rep(k,j+1,3)
51               dp[i][j]=max(dp[i][j],dp[i-1][k]+W[i][j]);
52         else
53           Rep(j,2,3)
54             For(k,j-1)
55               dp[i][j]=max(dp[i][j],dp[i-1][k]+W[i][j]);
56     }      
57     if(state==2) ans=max(ans,dp[n][1]);
58     else         ans=max(ans,max(dp[n][2],dp[n][1]));
59 }
60 
61 int main(){
62     freopen("garden.in","r",stdin);
63     freopen("garden.out","w",stdout);
64     read(n);
65     For(i,n){
66         read(W[i][1]);read(W[i][2]);read(W[i][3]);
67     }
68     Dp1(1,1);Dp1(1,2);
69     Dp2(0,2);Dp2(0,3);
70     cout<<ans<<endl;
71     return 0;
72 }
T1_100(70改)

相关文章:

  • 2022-02-14
  • 2021-12-02
  • 2021-08-18
  • 2021-10-01
  • 2021-05-17
  • 2021-07-11
  • 2021-12-16
  • 2022-02-18
猜你喜欢
  • 2021-11-18
  • 2021-06-10
  • 2021-06-22
  • 2022-02-02
  • 2021-06-12
  • 2021-07-25
  • 2021-09-16
相关资源
相似解决方案