http://acm.cs.ecnu.edu.cn/problem.php?problemid=2112
题意:给出时间上限,并给出每道题需要完成的时间以及得到的价值,求能得到的最大价值
与01背包不同的是,这题的时间最大10^9,即容量为这么多,不能直接对容量DP,
但发现每道题获得的价值有上限200,且n最大为100,就可以对价值进行DP,然后得到所有价值中时间小于等于给出最大时间的最大值
即 dp[i]为获得价值为i需要花费的最短时间,转移方程为dp[i]=min{dp[i],dp[i-V]+t}; 选出{max(i)|dp[i]<=tMax,0<=i<=Vmax}
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<map> 2 #include<set> 3 #include<list> 4 #include<cmath> 5 #include<ctime> 6 #include<queue> 7 #include<stack> 8 #include<cctype> 9 #include<cstdio> 10 #include<string> 11 #include<cstdlib> 12 #include<cstring> 13 #include<iostream> 14 #include<algorithm> 15 using namespace std; 16 const int maxn=105; 17 const int inf=0x3f3f3f3f; 18 int t[maxn],v[maxn]; 19 int dp[200*maxn]; 20 int main(){ 21 int T; 22 cin>>T; 23 while(T--){ 24 int n,l; 25 scanf("%d%d",&n,&l); 26 int Max=0; 27 for(int i=1;i<=n;i++){ 28 scanf("%d%d",t+i,v+i); 29 Max+=v[i]; //小优化 30 } 31 for(int i=1;i<=Max;i++) //获得0价值时需要0的时间,其他的就姑且设为最大值(因为要取min) 32 dp[i]=inf; 33 dp[0]=0; 34 for(int i=1;i<=n;i++) 35 for(int j=Max;j>=v[i];j--){ 36 dp[j]=min(dp[j-v[i]]+t[i],dp[j]); 37 } 38 int ans=0; 39 for(int i=0;i<=Max;i++){ 40 if(dp[i]<=l) //选取其中花时间小于等于给定时间中 价值最高的 41 ans=max(ans,i); 42 } 43 printf("%d ",ans); 44 } 45 return 0; 46 }