4831: [lydsy1704月賽]序列操作
time limit: 1 sec memory limit: 128 mb
submit: 207 solved: 70
[submit][status][discuss]
description
給定乙個長度為 n 的非負整數序列 a_1,a_2,…a_n 。你可以使用一種操作:選擇在序列中連續的兩個正整數,
並使它們分別減一。當你不能繼續操作時遊戲結束,而你的得分等於你使用的操作次數。你的任務是計算可能的最小
得分和最大得分。
input
第一行包含乙個正整數 t ,表示有 t 組資料,滿足 t ≤ 200 。
接下來依次給出每組測試資料。對於每組測試資料:
第一行包含乙個正整數 n ,滿足 1 ≤ n ≤ 10^5 。
第二行包含 n 個非負整數,表示 a_1,a_2,…a_n ,滿足 σa_i ≤ 10^6 。
約 5 組資料滿足 n ≥ 10^3 或 σa_i ≥ 10^4 。
output
對於每組測試資料
輸出一行兩個非負整數,用乙個空格隔開,前者表示可能的最小得分,後者表示可能的最大得分。
sample input
1 2 1 3
1 2 1 1 3
sample output
2 22 3
hint
source
鳴謝tangjz提供試題
顯然是個dp題了。
f[i][j][0/1],表示做到第i個數,他的值為j,前面的數是否存在時的最小運算元
考慮從f[i]轉移到i+1
當j<=a[i+1]的時候,同時減去j
f[i][j][0/1]->f[i+1][a[i+1]-j][0]
當j>a[i+1]的時候,同時減去a[i+1]
f[i][j][0]->f[i+1][0][1]
當i-1為0時,列舉k<=min(j-1,a[i+1])
f[i][j][0]->f[i+1][a[i+1]-k][1]
容易發現當k從大到小列舉的時候,只要算f[i][j][0]的字尾最小值即可。
最大值類似處理即可
#include
#include
#include
#include
#include
#include
#include
using
namespace
std;
typedef
long
long ll;
typedef
double db;
int n,m;
inline
int read()
const
int inf=707406378;
const
int n=1e6+7;
int f[n][2],g[n][2],h[n][2],a[n],max;
inline
void solve()
max=0;
for(int i=1;i<=n;++i) a[i]=read(),max=max(max,a[i]);
// memset(f,127/3,sizeof(f));
for(int i=0;i<=max;++i) f[i][0]=f[i][1]=inf;
f[a[1]][0]=0;
for(int i=1;ifor(int j=0;j<=a[i];++j) h[j][0]=f[j][0],h[j][1]=f[j][1];
for(int j=0;j<=a[i];++j) f[j][0]=f[j][1]=inf;
for(int j=0;j<=a[i];++j)
int tmp=1e9,t=min(a[i]-1,a[i+1]);
for(int j=t+1;j<=a[i];++j) tmp=min(tmp,h[j][0]);
for(int k=min(a[i]-1,a[i+1]);k>=0;--k)
}int tmp=min(f[0][1],f[0][0]);
for(int i=1;i<=a[n];++i)
tmp=min(tmp,f[i][0]);
printf("%d ",tmp);
for(int i=0;i<=max;++i) f[i][0]=f[i][1]=0;
// memset(f,0,sizeof(f));
f[a[1]][0]=1;
for(int i=1;ifor(int j=0;j<=a[i];++j) h[j][0]=f[j][0],h[j][1]=f[j][1];
for(int j=0;j<=a[i];++j) f[j][0]=f[j][1]=0;
for(int j=0;j<=a[i];++j)
if(h[j][0]||h[j][1])
int tmp=0,t=min(a[i]-1,a[i+1]);
for(int j=t+1;j<=a[i];++j) tmp=max(tmp,h[j][0]);
for(int k=min(a[i]-1,a[i+1]);k>=0;--k)
}tmp=0;
if(f[0][1]!=inf) tmp=max(tmp,f[0][1]);
if(f[0][0]!=inf) tmp=max(tmp,f[0][0]);
for(int i=1;i<=a[n];++i)
if(f[i][0]!=inf)
tmp=max(tmp,f[i][0]);
printf("%d\n",tmp-1);
}int main()
牛客小白月賽 小A的回文串
時間限制 c c 2秒,其他語言4秒 空間限制 c c 262144k,其他語言524288k 64bit io format lld 一行乙個字串表示給定的字串s一行乙個字串表示給定的字串s一行輸出乙個整數,表示通過這樣的操作後可以得到最大回文子串的長度。示例1 複製dcbaabc複製 7將前面的...
牛客小白月賽4 F 等價串題解
演算法分析 解題 一串長度為n的字串a和一串長度為m的字串b。並且這兩串字串只會含有0或1。鐵子可以對字串a執行兩種操作,兩種操作可以執行任意次。現在問,字串a可以變成字串b嗎?第一行有乙個整數t,表示有 t 1 t 1000 組測試資料。接下來的每組資料,第一行有兩個整數n,m 1 n,m 100...
洛谷 3月月賽T4 序列 貪心構造 DP
傳送門 luogup5241 一波找規律嘗試出n 4n 4 n4分做法,然而實際上是個貪心構造轉dp 考慮如何構造出一組合法序列 首先讓所有邊首尾相連形成鏈,如果scc數量產生變化,就縮鏈上開頭的一部分。在兼顧scc數量變化的同時,其它邊均貪心地用於串鏈,直到所有點都被串在了鏈上 這時就可以隨便連了...