zoukankan      html  css  js  c++  java
  • [HAOI2016] 字符合并

    给定一个长度为 (n)(01) 串,每次可以将相邻的 (k) 个字符合并,得到一个新的字符并获得一定的分数。求所能获得的最大分数。

    (n leq 300, k leq 8)

    Solution

    显然长为 (l) 的一段可以合并成长为 ((l-1)mod 7 +1) 的一段

    (f[l][r][s]) 表示将 ([l,r]) 合并成状态 (s) 的最大分数,考虑转移,枚举哪一部分合成了最后一位,很显然这部分的长度一定是 (7k+1) 的形式

    #include <bits/stdc++.h>
    using namespace std;
    #define int long long
    const int N = 305;
    int n,k,s[N],c[N],w[N],f[N][N][N];
    
    signed main() {
        ios::sync_with_stdio(false);
        cin>>n>>k;
        for(int i=1;i<=n;i++) cin>>s[i];
        for(int i=0;i<1<<k;i++) {
            cin>>c[i]>>w[i];
        }
        memset(f,-0x3f,sizeof f);
        for(int i=1;i<=n;i++) f[i][i][s[i]]=0;
        for(int l=2;l<=n;l++) {
            for(int i=1;i+l-1<=n;i++) {
                int j=i+l-1;
                int len=(l-1)%(k-1)+1;
                if(len==1) {
                    for(int s=0;s<1<<k;s++) {
                        for(int x=j-1;x>=i;x-=k-1) {
                            f[i][j][c[s]]=max(f[i][j][c[s]],f[i][x][s>>1]+f[x+1][j][s&1]+w[s]);
                        }
                    }
                }
                else {
                    for(int s=0;s<1<<len;s++) {
                        for(int x=j-1;x>=i;x-=k-1) {
                            f[i][j][s]=max(f[i][j][s],f[i][x][s>>1]+f[x+1][j][s&1]);
                        }
                    }
                }
            }
        }
        int ans=0;
        for(int i=0;i<(1<<k);i++) ans=max(ans,f[1][n][i]);
        cout<<ans;
    }
    
    
  • 相关阅读:
    各种类型的Dialog
    短信验证码的使用
    监听开机广播
    实现点击两次返回键退出
    Android 遮罩层效果--制作圆形头像
    Native方法的使用
    如何给数字添加分隔符
    自定义Toast
    Android px、dp、sp之间相互转换
    android:scrollbarStyle属性及滚动条和分割线覆盖问题
  • 原文地址:https://www.cnblogs.com/mollnn/p/12419808.html
Copyright © 2011-2022 走看看