I - Installing Apps 貪心+01揹包
阿新 • • 發佈:2020-10-05
I - Installing Apps 貪心+01揹包
題目大意:
有n種手機軟體,每一種軟體的安裝包大小是d,安裝後的軟體大小是s(刪除了安裝包),那麼若有c的手機記憶體,最多能安裝多少個手機軟體
題解:
貪心,用微調法可以確定貪心的策略,也就是排序的依據。
微調法就是調整前後兩個的順序,來求需要的容量,越小的在越前面。
然後就是一個01揹包,但是01揹包寫的好搓。
#include <bits/stdc++.h> #define inf 0x3f3f3f3f #define inf64 0x3f3f3f3f3f3f3f3f using namespace std; typedef unsigned long long ull; typedef long long ll; const int maxn = 550; struct node{ int d,s,id; node(int d=0,int s=0,int id=0):d(d),s(s),id(id){} }e[maxn]; bool cmp(node a,node b){ return max(a.s,a.d)-a.s>max(b.d,b.s)-b.s; } int dp[maxn][11000]; /** dp[i][j] 表示對於前面i個物品,選擇之後花費了j的容量下載的最大的數量 **/ vector<int>a; int main(){ int n,c; scanf("%d%d",&n,&c); for(int i=1;i<=n;i++){ int x,y; scanf("%d%d",&x,&y); e[i] = node(x,y,i); } sort(e+1,e+1+n,cmp); memset(dp,0xef,sizeof(dp)); dp[0][0] = 0; int ans = 0,pos = 0,v = 0; for(int i=1;i<=n;i++){ // printf("i = %d s = %d d = %d\n", i,e[i].s,e[i].d); for(int j=0;j<=c;j++){ if(c-j>=e[i].s&&c-j>=e[i].d){ // printf("j = %d\n", j); dp[i][j+e[i].s]=max(dp[i][j+e[i].s],dp[i-1][j]+1); // printf("dp[%d][%d]=%d\n", i,j+e[i].s,dp[i][j+e[i].s]); if(dp[i][j+e[i].s]>ans){ ans = dp[i][j+e[i].s]; pos = j+e[i].s; v = i; } } dp[i][j] = max(dp[i][j],dp[i-1][j]); } } a.clear(); while(v>0){ if(dp[v][pos]==dp[v-1][pos-e[v].s]+1) pos = pos-e[v].s,a.push_back(e[v].id); v = v - 1; } printf("%d\n", ans); for(int i=a.size()-1;i>=0;i--) printf("%d ", a[i]); printf("\n"); }