日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[HAOI2016]字符合并(ing)

發布時間:2023/12/3 编程问答 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [HAOI2016]字符合并(ing) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

[HAOI2016]字符合并

時間限制:C/C++ 1秒,其他語言2秒 空間限制:C/C++ 262144K,其他語言524288K 64bit IO Format: %lld

題目描述

有一個長度為 n 的 01 串,你可以每次將相鄰的 k 個字符合并,得到一個新的字符并獲得一定分數。得到的新字符和分數由這 k
個字符確定。你需要求出你能獲得的最大分數。 輸入描述: 第一行兩個整數n,k。 接下來一行長度為n的01串,表示初始串。
接下來2k行,每行一個字符ci和一個整數wi,ci
表示長度為k的01串連成二進制后按從小到大順序得到的第i種合并方案得到的新字符,wi表示對應的第i種方案對應獲得的分數。 1 ≤ n ≤
300,0 ≤ ci ≤ 1,wi ≥ 1, k ≤ 8

輸出描述:

輸出一個整數表示答案

示例1
輸入
復制

3 2 101 1 10 1 10 0 20 1 30

輸出
復制

40

題解:

一開始愣是沒看懂題意
長度為k的01串連成二進制后按從小到大順序,這句話我們用樣例來講就是
00,01,10,11這四個從小到大排列
分數分別是輸入的10,10,20,30

參考題解
區間dp+狀壓dp
dp[l][r][s]表示區間[l,r]合并為s的最小代價
經過推到可以得到:當串的長度為 lenlen 時,最后該串的長度為 (len-1) mod (k-1)+1
區間dp問題就是枚舉中間的端點,把區間[l,r]拆分成[l,mid]和[mid+1,r]

狀態定義:

f[l][r][S<<1]=max(f[l][r][S<<1],f[l][mid][S]+f[mid+1][r][0]); f[l][r][S<<1|1]=max(f[l][r][S<<1|1],f[l][mid][S]+f[mid+1][r][1]);

區間[mid+1,r]相當于已經合并完了,因為合并完的值就是0或1,直接加到前面區間[l,mid]上,f[l][mid][S]則是看[l,mid]這段區間合并成多少

當區間長度正好為k時,就直接合并,更新數據(用兩個臨時變量先儲存)
g[c[S]]=max(g[c[S]],f[l][r][S]+w[S]);
區間[l,r]合并為c[S]的最大值,然后
f[l][r][0]=g[0];f[l][r][1]=g[1];
g[]就是臨時變量

代碼:

#include <bits/stdc++.h> using namespace std; #define LL long long #define INF 0x3f3f3f3f LL f[310][310][(1<<8)+20]; char s[310]; int b[(1<<8)+20]; LL c[(1<<8)+20]; int main() {int n,m,k,i,j;scanf("%d%d",&n,&k);scanf("%s",s+1);for(i=0; i<(1<<k); ++i)scanf("%d%lld",b+i,c+i);memset(f,-INF,sizeof(f));LL inf=f[0][0][0];for(i=1; i<=n; ++i) f[i][i][s[i]-'0']=0;for(int len=2; len<=n; ++len){for(i=1; i+len-1<=n; ++i){j=i+len-1;int l=(j-i)%(k-1);if(!l) l=k-1;for(int las=j; las>=i; las-=k-1){for(int S=0; S<(1<<l); ++S){if(f[i][las-1][S]==inf) continue;if(f[las][j][0]!=inf)f[i][j][S<<1]=max(f[i][j][S<<1],f[i][las-1][S]+f[las][j][0]);if(f[las][j][1]!=inf);f[i][j][S<<1|1]=max(f[i][j][S<<1|1],f[i][las-1][S]+f[las][j][1]);}}if(l==k-1){LL g[2]= {inf,inf};for(int S=0; S<(1<<k); ++S){if(f[i][j][S]!=inf){g[b[S]]=max(g[b[S]],f[i][j][S]+c[S]);}}f[i][j][0]=g[0];f[i][j][1]=g[1];}}}LL ans=0;int l=n%(k-1)?n%(k-1):k-1;for(i=0; i<(1<<l); ++i)ans=max(ans,f[1][n][i]);cout<<ans<<endl;return 0; }

總結

以上是生活随笔為你收集整理的[HAOI2016]字符合并(ing)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。