Bone Collector II
Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2464 Accepted Submission(s): 1295 Problem DescriptionThe title of this problem is familiar,isn't it?yeah,if you had took part in the "Rookie Cup" competition,you must have seem this title.If you haven't seen it before,it doesn't matter,I will give you a link: Here is the link:http://acm.hdu.edu.cn/showproblem.php?pid=2602 Today we are not desiring the maximum value of bones,but the K-th maximum value of the bones.NOTICE that,we considerate two ways that get the same value of bones are the same.That means,it will be a strictly decreasing sequence from the 1st maximum , 2nd maximum .. to the K-th maximum. If the total number of different values is less than K,just ouput 0. InputThe first line contain a integer T , the number of cases. Followed by T cases , each case three lines , the first line contain two integer N , V, K(N <= 100 , V <= 1000 , K <= 30)representing the number of bones and the volume of his bag and the K we need. And the second line contain N integers representing the value of each bone. The third line contain N integers representing the volume of each bone. OutputOne integer per line representing the K-th maximum of the total value (this number will be less than 231). Sample Input3 5 10 2 1 2 3 4 5 5 4 3 2 1 5 10 12 1 2 3 4 5 5 4 3 2 1 5 10 16 1 2 3 4 5 5 4 3 2 1
Sample Output12 2 0
題意:給你n個骨頭的信息(價值和體積),給你一個體積為V的背包,要你求出這個背包裝骨頭得到的所有價值中第K大的
思索了半天不知道就百度,百度之後還是不懂結果就看接替報告,看了半天看是不知道博主們想說的是什麼,於是就對照代碼對照數據事勁瞅,然後才差不多懵懵懂
解析:常規的01背包是求的V體積的容器中裝物品得到的最大價值,像這個要求的是第K大的就有點力不從心了,所以要加點料,背包九講裡邊學來的公式是
f[x]=max[f[x-v]+w,f[x]),要求K大的值肯定要記錄更多數據才行,所以給數組加一維變成f[ ][ ],第二維裡面就用來記錄K個數據,分別是最大遞減到K大,然後直接用01背包的方法求就是了,本來f[x][1~k]中只有K個數據,對於1~k全部都作上面的那個公式處理一下,然後得到的數據是2*K個,懂吧?分別是f[x][k]和f[x-v][k]+w,然後這些數據取最大的K個記錄下來就行了
其實這個我還是不太懂,驗證了半天就是得不出讓我心安理得的結論,為什麼這樣就能保證結果中能得出所有值,其中的一些小插曲就不說了,看代碼吧!
#include#include #include using namespace std; int main (void) { int n,v,m,i,j,k,l,t; __int64 dp[1111][33],a[2][33],vol[111],val[111]; scanf("%d",&t); while(t--&&~scanf("%d%d%d",&n,&v,&m)) { for(i=0;i =vol[i];j--) { for(k=0;k
總結:這算是一個新的寫法,至少對於我來說,我還沒有真正弄懂這個做法,只是簡單的記下來了,記下來是沒用的,要理解才行,這兩天就多瞅瞅吧,直到弄明白了再說!