hihoCoder 1285 [Offer收割]程式設計練習賽3-3
阿新 • • 發佈:2018-12-18
[Offer收割]程式設計練習賽3——第3題
這次練習賽感覺比前兩次練習賽簡單一點,第1第2題就不說了。
#1285 : 智力競賽
時間限制: 5000ms 單點時限: 1000ms 記憶體限制: 256MB
描述
小Hi、小Ho還有被小Hi強拉來的小Z,準備組隊參加一個智力競賽。競賽採用過關制,共計N個關卡。在第i個關卡中,小Hi他們需要獲得Ai點分數才能夠進入下一關。每一關的分數都是獨立計算的,即使在一關當中獲得超過需要的分數,也不會對後面的關卡產生影響。
小Hi他們可以通過答題獲得分數。答對一道題獲得S點分數,答錯一道題獲得T點分數。在所有的N個關卡中,小Hi他們一共有M次答題機會。在每個關卡中,都可以在累計答題次數不超過M的情況下使用任意次的答題機會。
那麼現在問題來了,對於給定的N、M、S、T和A,小Hi他們至少需要答對多少道題目才能夠完成所有的關卡呢?
輸入
每個輸入檔案包含多組測試資料,在每個輸入檔案的第一行為一個整數Q,表示測試資料的組數。
每組測試資料的第一行為四個正整數N、M、S和T,意義如前文所述。
第二行為N個正整數,分別表示A1~AN。
對於40%的資料,滿足1<=N,M<=100
對於100%的資料,滿足1<=N,M<=1000,1<=T<S<=10,1<=Ai<=50
對於100%的資料,滿足1<=Q<=100
輸出
對於每組測試資料,如果小Hi他們能夠順利完成關卡,則輸出一個整數Ans,表示小Hi他們至少需要答對的題目數量,否則輸出No。
樣例輸入1
2 10 9 1
12 35
樣例輸出
5
思路: 明顯是動規。dp[i][j]表示過前i關答對j題時,最少要答錯多少題 感覺dp初始化寫得有點亂,而且狀態轉移也沒有很認真考究邏輯細節,一提交居然直接ac了。。有點小高興
#include<iostream>
#include<string.h>
#include<limits.h>
using namespace std;
#define MAXN 1003
#define MAXM 1003
int dp[MAXN][MAXM];
int a[MAXN];
int n,m,s,t;
int main(){
int Q,k,p;
scanf("%d",&Q);
while(Q--){
memset(dp,0,MAXM*sizeof(int));
memset(a,0,sizeof(a));
scanf("%d%d%d%d",&n,&m,&s,&t);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
fill(dp[i],dp[i]+MAXM,INT_MAX);
}
for(int i=1;i<=n;i++){
k=(a[i]+s-1)/s;
for(int j=0;j<=m;j++){
for(int h=0;h<=k;h++){
p=a[i]-h*s;
p=(p<=0?0:((p+t-1)/t));
dp[i][j+h]=min(dp[i][j+h],dp[i-1][j]+p);
}
}
}
bool has=false;
for(int i=0;i<=m;i++){
if(i+dp[n][i]<=m){
has=true;
cout<<i<<endl;
break;
}
}
if(!has)
cout<<"No"<<endl;
}
}