3732 Ahui Writes Word 解题报告
哈哈,今天是过年哦,祝大家 新年快乐~
看这题吧,乍一看这题是01背包问题。看看这N和C的范围,用01背包做的话,Time Limit Exceeded。
网上百度了一下,找到了解决方法。因为0≤Vi,Ci≤10,所以可以进行优化。即在V-10的范围内,直接选择性价比高的单词,后者使用01背包优化。至于问什么可以这么做,我只是觉得很合理,具体的证明我还得找找。
#include<iostream> #include<algorithm> using namespace std; int dp[10001]; char str[20]; struct s { int c,v; } w[100001]; int cmp(const void* a,const void* b) { return (((s*)a)->c*((s*)b)->v)-(((s*)a)->v*((s*)b)->c); } int main() { int i,j,n,m,sc,sv,t,v; while(~scanf("%d%d",&n,&m)) { m-=10; for(i=0;i<n;i++) { scanf("%s%d%d",str,&w[i].v,&w[i].c); if(w[i].v==0) { i--; n--; } } qsort(w,n,sizeof(s),cmp); for(i=sc=sv=0;i<n;i++) { sc+=w[i].c; if(sc>m) { sc-=w[i].c; memset(dp,0,sizeof(dp)); for(v=m-sc+10;i<n;i++) for(j=v;j>=w[i].c;j--) if(dp[j]<(t=dp[j-w[i].c]+w[i].v)) dp[j]=t; sv+=dp[v]; break; } sv+=w[i].v; } printf("%d\n",sv); } }
大过年的,还是很开心呀。这题还可以用多重背包来做,不过我还没学。。。等学了我会补上的。生命不息,追求不止。。。愿新年,开心。