“亚信科技杯”南邮第七届大学生程序设计竞赛之网络预赛 (K L题解)
“亞信科技杯”南郵第七屆大學(xué)生程序設(shè)計競賽之網(wǎng)絡(luò)預(yù)賽 (K L題解)?
?
第一次出題,果然背鍋了,L題由于數(shù)據(jù)問題,讓兩種不對的方法ac了,分別是:H<0時取前一天送上花(應(yīng)該是wa,思路錯誤),第二種是dfs的(應(yīng)該是TLE),但是數(shù)據(jù)太小。所以,就當(dāng)強行送溫暖了,不過不希望誤導(dǎo)大家,大家有空再思考思考正解~~
?
首先是K題:
法師
時間限制(普通/Java)?:?1000 MS/?3000 MS?? ? ? ???運行內(nèi)存限制 : 65536 KByte總提交 : 175 ? ? ? ?? ? 測試通過 : 30?
題目描述
說到法師,也許大家第一反應(yīng)便是脆弱的身軀與強大的爆發(fā)能力。誠然如此,在《爐石傳說》中,法師擁有著最高傷害的單體法術(shù)——炎爆術(shù),同時還有同樣高傷害的火球術(shù)。但法師并不僅限于此,如果說這兩張火系法術(shù)代表著的是法師的爆發(fā)。那么冰系法術(shù)就代表了法師的控制,冰霜新星、冰錐術(shù)以及暴風(fēng)雪和寒冰箭都能夠使對手凍結(jié)。
每張卡牌能造成一定的傷害,同時也要花費一定的法力水晶。當(dāng)法力水晶不夠的時候,你便不能打出相應(yīng)的卡牌。
為了簡單起見,我們只考慮以下幾張卡牌。
寒冰箭?:消耗2點法力水晶,對一個角色造成3點傷害,并使其凍結(jié)。
冰槍術(shù):消耗1點法力水晶,使一個角色凍結(jié),如果它已經(jīng)被凍結(jié),則改為對其造成4點傷害。
火球術(shù):消耗4點法力水晶,造成6點傷害。
炎爆術(shù):消耗10點法力水晶,造成10點傷害。
現(xiàn)在,告訴你現(xiàn)在擁有的法力水晶,以及手上擁有的這四種卡牌的數(shù)目(可能為0),問你能對敵方英雄造成多少點傷害。
輸入
?
第一行為一個正整數(shù)T,表示有T組數(shù)據(jù)。
每組數(shù)據(jù)第一行有1個整數(shù):?n表示當(dāng)前擁有的法力水晶個數(shù)0<=n<=10。
第二行為四個整數(shù)a,b,c,d分別表示擁有寒冰箭、冰槍術(shù)、火球術(shù)、炎爆術(shù)的數(shù)目。0<=a,b,c,d<=10.
?
輸出
?
一個整數(shù)表示最大可能造成的傷害值。
?
樣例輸入
2
9
0?0?3?0
5
2?2?1?1
樣例輸出
12
11
?
題目來源
NUPT
?
題意:
告訴你現(xiàn)在擁有的法力水晶(n),以及手上擁有的這四種卡牌的數(shù)目(可能為0),問你能對敵方英雄造成多少點傷害。
ps:冰凍的特效是一旦冰凍就會一直冰凍。
?
題解:
1.想作為一道水題的,不想為難大家,所以數(shù)據(jù)范圍均<=10,直接四重循環(huán)暴力即可,最后判斷一下關(guān)于冰凍的事情。(如果沒有寒冰箭的話,要先浪費一個冰槍術(shù))
2.如果數(shù)據(jù)范圍比較大的話,暴力就會TLE,這時候,可以考慮先用背包的思路(動態(tài)規(guī)劃的一種),將火球術(shù)和炎爆術(shù)進行預(yù)處理。
得到dp[i],表示使用了i點法力水晶,可以造成的最大傷害,在此基礎(chǔ)上,考慮寒冰箭與冰槍術(shù)了。
2.1 如果剩余法力水晶充足,一起加上。
2.2 如果剩余法力不足,分為兩種情況:使用寒冰箭與不使用寒冰箭。
2.2.1 不使用寒冰箭,把冰槍術(shù)的傷害加上即可。
2.2.2 使用寒冰箭,那么先拿出一張寒冰箭,然后優(yōu)先用冰槍術(shù)(不涉及到冰凍問題,冰槍術(shù)的性價比要高),然后再加上寒冰箭。
?
標(biāo)程:
這里先給出暴力法的標(biāo)程,有興趣的同學(xué)可以嘗試一下,如果數(shù)據(jù)比較大(1<=n,a,b,c,d<=100000)的情況,如何用上述方法解決。
?
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 int main() 5 { 6 int T; 7 scanf("%d", &T); 8 while(T--) 9 { 10 int a, b, c, d, n; 11 scanf("%d", &n); 12 scanf("%d %d %d %d", &a, &b, &c, &d); 13 int ans = 0; 14 15 for(int i = 0; i <= a; i++) 16 { 17 for(int j = 0; j <= b; j++) 18 { 19 for(int k = 0; k <= c; k++) 20 { 21 for(int l = 0; l <= d; l++) 22 { 23 if(2 * i + 1 * j + 4 * k + 10 * l <= n) 24 { 25 if(i > 0) //用寒冰箭冰凍 26 ans = max(ans, 3 * i + 4 * j + 6 * k + 10 * l); 27 else 28 { 29 if(j >= 1) //用冰槍術(shù)冰凍 30 ans = max(ans, 4 * (j - 1) + 6 * k + 10 * l); 31 else 32 ans = max(ans, 6 * k + 10 * l); 33 } 34 } 35 } 36 } 37 } 38 } 39 printf("%d\n", ans); 40 } 41 }?
?
?
然后是L:
?
送花
時間限制(普通/Java)?:?1000 MS/?3000 MS?? ? ? ???運行內(nèi)存限制 : 65536 KByte總提交 : 117 ? ? ? ?? ? 測試通過 : 42?
題目描述
萌妹紙一般都比較喜歡漂亮的鮮花。每逢各種節(jié)日,她們都想收到鮮花作為禮物。如果你是有妹紙滴人,經(jīng)常不送妹紙花的話,結(jié)果可想而知了。
當(dāng)然咯,妹紙都是通情達理的,不會因為某幾次你木有送花,就發(fā)你好人卡了。王童鞋作為一個比較節(jié)儉(摳門)的人便知道這一道理,因此他想在妹紙不給他發(fā)好人卡的前提下,送盡量少的花。
為了簡單起見,我們定義一個妹紙的幸福指數(shù)H(初始為0?)。如果某天幸福指數(shù)H小于0,那就。。。
如果某天妹紙收到了花,幸福指數(shù)H會增加ai,如果沒收到,會下降bi。不同的日子送花對幸福指數(shù)的增加可能會有所不同,比如在2月14號送花就會比2月15號效果好~
即告訴你總天數(shù)n(1<=n<=365),每天收到花幸福指數(shù)的增加值ai(1<=ai<=10),沒收到花幸福指數(shù)的降低值bi,求為了讓妹紙的幸福指數(shù)H一直>=0,王童鞋至少要送妹紙多少朵花。
輸入
?
第一行為一個正整數(shù)T,表示有T組數(shù)據(jù)。
每組數(shù)據(jù)第一行有1個整數(shù):?n表示總天數(shù)1<=n<=365。
第二行為n個整數(shù)ai表示第i天收到花幸福指數(shù)的增加值,1<=ai<=10。第三行為n個整數(shù)bi表示第i天沒收到花幸福指數(shù)的下降值,1<=bi<=10。
?
輸出
?
一個整數(shù)表示最少需要送多少朵花。
?
樣例輸入
2
1
3
4
5
5?2?10?1?1
1?1?1?5?5
樣例輸出
1
2
?
題目來源
NUPT
?
?
這題要和大家說抱歉了,L題由于數(shù)據(jù)問題,讓兩種不對的方法ac了,分別是:H<0時取前一天送上花(應(yīng)該是wa,思路錯誤),第二種是dfs的(應(yīng)該是TLE),但是數(shù)據(jù)太小。所以,就當(dāng)強行送溫暖了,不過不希望誤導(dǎo)大家,大家有空再思考思考正解~~
?
題意:
告訴你總天數(shù)n(1<=n<=365),妹紙的幸福指數(shù)H初始為0,每天收到花幸福指數(shù)的增加值ai(1<=ai<=10),沒收到花幸福指數(shù)的降低值bi,求為了讓妹紙的幸福指數(shù)H一直>=0,王童鞋至少要送妹紙多少朵花。
?
題解:
1.本來是想出個動態(tài)規(guī)劃的題目:
即每天只有兩種選擇,送或者不送。那么可以定義dp[i][j]含義為前i天,讓妹紙的幸福值達到j(luò)所需要的最少花的數(shù)目。最后枚舉一下最后一天即可。
轉(zhuǎn)移方程也不難:
送花的話:dp[i][ j+a[i]?]=min(dp[i][ j+a[i]?],dp[i-1][j]+1);
不送花的話:dp[i][ j-b[i]?]=min(dp[i][ j-b[i]?],dp[i-1][j]);
?
2.這題也可以用貪心的思路,不過不是簡單的,H<0時取前一天送上花。而是應(yīng)該,H<0時取前面沒送花的某天,如果改為送花,選擇送花收益最大的一天送花。
(能讓妹紙幸福值變得最大,這里的增加不是指的a[i],而是a[i]+b[i])
具體的實現(xiàn)可以用優(yōu)先隊列。如果H>=0,我們不選,H-=b[i],同時將 a[i]+b[i]的值存入優(yōu)先隊列。
(因為,如果這天改為送花,妹紙的幸福指數(shù)不但不會下降b[i],反而會上升a[i],一來一去收益為?a[i]+b[i])。
然后,如果h<0,將優(yōu)先隊列的隊首元素出隊列,記為temp,h+=temp
?
同樣,這里只給出動態(tài)規(guī)劃的標(biāo)程,希望大家思考如何寫出正確的貪心程序。當(dāng)數(shù)據(jù)范圍變成,1<=n<=100000,1<=ai<=10000,1<=bi<=10000.
?
?
1 #include <cstdio> 2 #include <cstring> 3 #include <stack> 4 #include <vector> 5 #include <algorithm> 6 7 #define ll long long 8 int const N = 405; 9 int const M = 205; 10 int const inf = 1000000000; 11 ll const mod = 1000000007; 12 13 using namespace std; 14 15 int T; 16 int n; 17 int dp[N][10*N]; 18 int mi; 19 int a[N]; 20 int b[N]; 21 int suma; 22 23 void ini() 24 { 25 int i; 26 mi=inf; 27 suma=0; 28 scanf("%d",&n); 29 memset(dp,-1,sizeof(dp)); 30 dp[0][0]=0; 31 for(i=1;i<=n;i++){ 32 scanf("%d",&a[i]); 33 suma+=a[i]; 34 } 35 for(i=1;i<=n;i++){ 36 scanf("%d",&b[i]); 37 } 38 } 39 40 void solve() 41 { 42 int i,j; 43 int temp; 44 for(i=1;i<=n;i++){ 45 for(j=0;j<=suma-a[i];j++){ 46 if(dp[i-1][j]==-1) continue; 47 temp=j+a[i]; 48 if(dp[i][temp]==-1){ 49 dp[i][temp]=dp[i-1][j]+1; 50 } 51 else{ 52 dp[i][temp]=min(dp[i][temp],dp[i-1][j]+1); 53 } 54 } 55 56 for(j=b[i];j<=suma;j++){ 57 if(dp[i-1][j]==-1) continue; 58 temp=j-b[i]; 59 if(dp[i][temp]==-1){ 60 dp[i][temp]=dp[i-1][j]; 61 } 62 else{ 63 dp[i][temp]=min(dp[i][temp],dp[i-1][j]); 64 } 65 } 66 } 67 68 for(j=0;j<=suma;j++){ 69 if(dp[n][j]==-1) continue; 70 mi=min(mi,dp[n][j]); 71 } 72 } 73 74 void out() 75 { 76 printf("%d\n",mi); 77 } 78 79 int main() 80 { 81 //freopen("data.in","r",stdin); 82 scanf("%d",&T); 83 for(int cnt=1;cnt<=T;cnt++) 84 //while(T--) 85 //while(scanf("%d",&n)!=EOF) 86 { 87 ini(); 88 solve(); 89 out(); 90 } 91 }?
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/njczy2010/p/4378596.html
總結(jié)
以上是生活随笔為你收集整理的“亚信科技杯”南邮第七届大学生程序设计竞赛之网络预赛 (K L题解)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: VMware Workstation创建
- 下一篇: 【位运算DFS/DLX】【HDU1426