POJ-1018 Communication System(dp)
阿新 • • 發佈:2020-11-06
題目描述
有 \(n(1\leq n \leq 100)\) 種裝置,每種裝置有 \(c_i(1\leq c_i\leq 100)\) 個廠家生產,裝置 \(i(1\leq i\leq n)\) 的第 \(j(1\leq j\leq c_i)\) 個廠家生產的裝置會存在兩個方面的差別:引數 \(a_{ij}\) 和價格 \(b_{ij}\)。
現在每種裝置都需要 \(1\) 個,設 \(\min\) 為選出的 \(n\) 件裝置中的最小引數,\(\text{sum}\) 為選出的 \(n\) 件裝置的總價格,求 \(\frac{\min}{\text{sum}}\) 的最大值。
分析
設 \(dp[i][j]\)
當 \(j\leq k\) 時,\(dp[i][j]=\min(dp[i][j],dp[i-1][k]+b_{ij})\)。
當 \(j>k\) 時,\(dp[i][k]=\min(dp[i][k],dp[i-1][k]+b_{ij})\)。
轉移的時候從 \(0\) ~ \(2000\) 列舉最小引數 \(j\);最後求答案的時候,列舉 \(i\in[0,2000]\),求 \(i/dp[n][i]\) 的最大值。
程式碼
#include <iostream> #include <cstdio> #include <cstring> using namespace std; int c[110],a[110][110],b[110][110]; int dp[120][2010]; int main() { int T; cin>>T; while(T--) { memset(dp,0x3f,sizeof(dp)); int n; cin>>n; for(int i=1;i<=n;i++) { scanf("%d",&c[i]); for(int j=1;j<=c[i];j++) scanf("%d %d",&a[i][j],&b[i][j]); } for(int i=1;i<=n;i++) { for(int j=1;j<=c[i];j++) { if(i==1) dp[1][a[1][j]]=min(dp[1][a[1][j]],b[1][j]); else { for(int k=0;k<=2000;k++) { if(dp[i-1][k]!=0x3f) { if(a[i][j]<=k) dp[i][a[i][j]]=min(dp[i][a[i][j]],dp[i-1][k]+b[i][j]); else dp[i][k]=min(dp[i][k],dp[i-1][k]+b[i][j]); } } } } } double ans=0.0; for(int i=0;i<=2000;i++) if(dp[n][i]!=0x3f) ans=max(ans,1.0*i/dp[n][i]); printf("%.3f\n",ans); } return 0; }