P2370 yyy2015c01 的 U 盘
https://www.luogu.com.cn/problem/P2370
动态规划背包,排序,二分
黄色题
动态规划背包,排序,二分
黄色题
思路一:01背包+排序
#include<cstdio> #include<algorithm> using namespace std; int n,p,s; int dp[1005];//dp[i]表示装i体积的东西能够得到的价值 struct node { int v,w; }a[1005];//在这里定义一个结构体,因为后面要用到排序 int cmp(node a,node b) { return a.v<b.v;//简单的排序 } int main() { scanf("%d%d%d",&n,&p,&s);//输入对应的文件总数,希望最小价值p和硬盘大小s for(int i=1;i<=n;i++) scanf("%d%d",&a[i].v,&a[i].w); sort(a+1,a+n+1,cmp); for(int i=1;i<=n;i++) for(int j=s;j>=a[i].v;j--)//01背包的模板 { dp[j]=max(dp[j],dp[j-a[i].v]+a[i].w); if(dp[s]>=p)//如果此时装满的情况下得到的价值已经超过了所需, //这里是用最终的结果去判断!!!!!!!! //那么当前物品的体积就是满足条件的最小体积(因为之前已经排过序了) { printf("%d",a[i].v);//直接输出,结束程序 return 0; } } printf("No Solution!"); //输出不满足条件的情况 }
思路二:01背包+二分答案
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MAXN = 1010; int f[MAXN],v[MAXN],w[MAXN]; int n,m,s; bool dp(int x) { memset(f,0,sizeof(f)); for (int i=1; i<=n; ++i) { if (v[i]>x) continue ; for (int j=s; j>=v[i]; --j) f[j] = max(f[j],f[j-v[i]]+w[i]); } if (f[s]<m) return false ; return true ; } int main() { scanf("%d%d%d",&n,&m,&s); for (int i=1; i<=n; ++i) { scanf("%d%d",&v[i],&w[i]); } int l = 0 , r = s, ans = -1; while (l<=r) { int mid = (l+r)>>1; if (dp(mid)) { ans = mid; r = mid-1; } else l = mid+1; } if (ans==-1) printf("No Solution!"); else printf("%d",ans); return 0; }