珂...珂...珂朵莉給你出了一道送分題:
給你乙個長為n的序列,和乙個數a,你可以從裡面選出最多m個數
乙個合法的選擇的分數定義為選中的這些數的和加上額外規則的加分:
有b個額外的規則,第i個規則即為:
對於這個序列的所有長為a的連續子區間,如果這個子區間中對應的給出的xi個位置都被選中了,則這次選擇的分數加上yi(yi可能為負數,這種情況下分數仍然要加上y)
第一行四個數n,m,a,b
之後一行n個數表示序列v
之後表示b個規則
每個規則先輸入兩個數xi和yi
之後一行xi個數,分別表示這給定的xi個位置
一行乙個數表示最大可能得到的分數示例1
複製
5 3 3 1複製2 3 3 3 3
2 233
1 3
示例2複製
5 3 3 1複製111 222 333 444 555
2 52
1 3
對於100%的資料,0 <= n <= 100 , 0 <= m <= 50 ,0<= a <= 16 , 0 <= b <= 100000, 所有出現的數的絕對值<=
600解題思路:
首先預處理出每個狀態下能得到的額外的分數,定義狀態dp【i】【j】【k】為前i個數中取j個數,最後a個數的狀態為k時的最大分數,那麼狀態轉移方程為:取當第i+1個數字時:
dp[1^flag][j+1][(k>>1)|(1<>1)|(1<>1)|(1<
不取第i+1個數字:dp[1^flag][j][k>>1]=max(dp[1^flag][j][k>>1],dp[flag][j][k]+eval[k>>1]);
這裡我用了滾動陣列。
#include#define inf 0x3f3f3f3fusing
namespace
std;
int eval[1
<<16
];int val[105
];int dp[2][55][1
<<16
];int
main()
for(int i=0;i)
eval[tem]+=y;
//cout
for(int i=(1
<1;i>=0;i--)
}for(int i=0;i<=m;i++)
}for(int j=0;j
}dp[
0][cnt][j]=max(dp[0][cnt][j],tem+eval[j]);
}int flag=0
;
for(int i=a;i)
}for(int j=0;j<=m;j++)
}flag=flag^1
; }
int ans=-inf;
for(int i=0;i<=m;i++)
}printf(
"%d\n
",ans);
return0;
}
牛客練習賽22 B 送分題
資料結構之神ccz又在出毒瘤資料結構了 神出了這樣乙個題 給你三個數,在這三個數中間任意加 或者是 然後可以隨便打括號,只要這個表示式合法 比如說1 2 3可以得到 不能改變這三個數的原順序 最大化表示式的值 輸入三行,每行乙個數 分別表示a,b,c輸出一行乙個數表示答案示例1 複製 1 23 複製...
牛客練習賽6 A 二分
有n只猴子,第i只猴子每過xi小時會連續吃香蕉yi小時。猴子從第二次開始每次休息結束後這只猴子連續吃香蕉的時間會增加zi小時。給定n只猴子,每乙隻的x i,yi,z i,以及時間t,求在前t小時中,所有猴子共吃了多少小時。對於乙隻猴子來說是這樣的 從第1小時開始 休息xi小時 1 x i 吃yi小時...
牛客練習賽9
時間限制 c c 1秒,其他語言2秒 空間限制 c c 32768k,其他語言65536k 64bit io format lld 珂朵莉想每天都給威廉送禮物,於是她準備了n個自己的本子 她想送最多的天數,使得每天至少送乙個本子,但是相鄰兩天送的本子個數不能相同 珂朵莉最多送幾天禮物呢 第一行乙個整...