這是一道dp題,比賽的時候沒做,省最後乙個小時的時候看了一下,感覺是,但是一下子沒有想出來思路。
後來看了一下題解,瞬間就頓悟了。然後就自己把方程寫出來了,一看和題解的不一樣,不過殊途同歸,只是狀態的表示不一樣,思路是一致的。
說一下思路,首先想到如果放紅塔的話,放在後面肯定比前面得到的值不小(多數情況是更大的),所以我們就列舉後面放紅塔的個數,得到最優解。
設dp[i][j]為前i個位置中,放j個綠塔造成的傷害。
那麼:dp[i][j]=max
其中dp[i-1][j-1]+((i-j)*z+t)*y*(j-1),的意思是:第i個位置放第j個綠塔(前i-1個位置放了j-1個綠塔),
那麼走到從i-1走到i造成的傷害就是((i-j)*z+t)*y*(j-1),(之前的綠塔累計造成傷害乘以藍塔累計延遲的時間)
dp[i-1][j]+((i-j-1)*z+t)*y*j 的意思是:前i-1個位置已經放了j個綠塔,第i個位置放藍塔,同理也要計算從i-1到i造成的傷害((i-j-1)*z+t)*y*j (綠塔累計造成傷害乘以藍塔累計延遲的時間)
方程的含義知道了,最後就是列舉後面又幾個紅塔:設dge為傷害,
dge=max( dge,dp[i][j]+(n-i)*(x+j*y)*((i-j)*z+t) ); 即後面放n-i個紅塔的最大傷害(dp[i][j]的傷害+後面n-i個紅塔和前面放綠塔,藍塔的綜合傷害。自己想一下就ok了)。
**如下:
#include#include#include#includeusing namespace std;
#define max 1555
__int64 x,y,z;
int n,t;
int t,c=0;
__int64 dp[max][max];
__int64 ans,dge;
__int64 max(__int64 a,__int64 b)
void init()
dp[i][j]=max( dp[i-1][j-1]+((i-j)*z+t)*y*(j-1),dp[i-1][j]+((i-j-1)*z+t)*y*j );}}
}void work()
ans=max(ans,dge);
}printf("case #%d: %i64d\n",c,ans);
}int main()
return 0;
}
多校聯合(4)
感覺這次數學題挺多的,這次的資料應該不能說水了,有的卡的確實挺厲害,但覺得有的題還是很無語,比如說那個trouble,二分感覺不超的,就是過不了,不是wa,就是tle,還會mle,乙個簡單的hash就可以過。是不是太卡演算法了。題目 這道題真沒什麼好說的 view code 1 include 2 ...
2013 多校聯合5
1005 若沒有邊權,則對點權從大到小排序即可。考慮邊,將邊權拆成兩半加到它所關聯的兩個點的點權中即可。因為當兩個人分別選擇不同的點時,這一權值將互相抵消。智商是硬傷啊 include include include includeusing namespace std double w 10000...
多校聯合訓練4 5773
解題方法 0可以轉化成任意整數,包括負數,顯然求lis時盡量把0都放進去必定是正確的。因此我們可以把0拿出來,對剩下的做o nlogn 的lis,統計結果的時候再算上0的數量。為了保證嚴格遞增,我們可以將每個權值s i 減去i前面0的個數,再做lis,就能保證結果是嚴格遞增的。ac include ...