【CF1252J】Tiling Terrace(DP)

题意:有一个长为n的串,每个字符是#或者.中的一个,#不超过50个

有3种覆盖串的方式:(.),(..),(.#.),分别能获得g1,g2,g3的收益,覆盖之间不能重叠

第一种方式不能使用超过K次,问能获得的最大总收益,可以不覆盖完所有n个字符

n<=1e5,0<=g1,g2,g3<=1e3

思路:显然#将串分割成了若干段,预处理出段数和每段的长度

设dp[i][j][0/1]为前i段用了j次方式一,最后一个#处有没有用方式三的最大总收益

枚举段中方式二的使用次数进行转移

可以不覆盖完n个体现在/2的下取整

理论上说应该会T,实际上只跑了63ms……

应该能用前缀最大值优化,已经跑过去了也不想写了……

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 typedef unsigned int uint;
 5 typedef unsigned long long ull;
 6 typedef long double ld;
 7 typedef pair<int,int> PII;
 8 typedef pair<ll,ll> Pll;
 9 typedef vector<int> VI;
10 typedef vector<PII> VII;
11 typedef pair<ll,ll>P;
12 #define N  100010
13 #define M  200010
14 #define INF 1e9
15 #define fi first
16 #define se second
17 #define MP make_pair
18 #define pb push_back
19 #define pi acos(-1)
20 #define mem(a,b) memset(a,b,sizeof(a))
21 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
22 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
23 #define lowbit(x) x&(-x)
24 #define Rand (rand()*(1<<16)+rand())
25 #define id(x) ((x)<=B?(x):m-n/(x)+1)
26 #define ls p<<1
27 #define rs p<<1|1
28 
29 const ll MOD=1e9+7,inv2=(MOD+1)/2;
30       double eps=1e-6;
31       int dx[4]={-1,1,0,0};
32       int dy[4]={0,0,-1,1};
33 
34 
35 ll dp[55][N][2];
36 int a[N];
37 char ch[N];
38 
39 int read()
40 {
41    int v=0,f=1;
42    char c=getchar();
43    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
44    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
45    return v*f;
46 }
47 
48 int main()
49 {
50     int n=read(),K=read();
51     ll g1,g2,g3;
52     scanf("%I64d%I64d%I64d",&g1,&g2,&g3);
53     scanf("%s",ch+1);
54     int top=1;
55     rep(i,1,n)
56      if(ch[i]=='#') top++;
57       else a[top]++;
58     while(top&&a[top]==0) top--;
59     if(top==0)
60     {
61         printf("0\n");
62         return 0;
63     }
64     memset(dp,0xcf,sizeof(dp));
65     dp[0][0][0]=0;
66     rep(i,1,top)
67      rep(j,0,K)
68      {
69         int t=min(a[i],j);
70         rep(k,0,t)
71         {
72             if(k<=a[i])   dp[i][j][0]=max(dp[i][j][0],dp[i-1][j-k][0]+(a[i]-k)/2*g2+k*g1);
73             if(k<=a[i]-1) dp[i][j][0]=max(dp[i][j][0],dp[i-1][j-k][1]+(a[i]-k-1)/2*g2+g3+k*g1);
74             if(k<=a[i]-1) dp[i][j][1]=max(dp[i][j][1],dp[i-1][j-k][0]+(a[i]-k-1)/2*g2+k*g1);
75             if(k<=a[i]-2) dp[i][j][1]=max(dp[i][j][1],dp[i-1][j-k][1]+(a[i]-k-2)/2*g2+g3+k*g1);
76         }
77      }
78     ll ans=0;
79     rep(i,0,K) ans=max(ans,dp[top][i][0]);
80     printf("%I64d\n",ans);
81     return 0;
82 }

 

posted on 2019-10-28 16:45  myx12345  阅读(267)  评论(0编辑  收藏  举报

导航