HDU2955:做这道题是,错误的认为题目所给的浮点型的数据都是精确到小数点后两位,然后把概率放大100倍,转换成为熟悉的01背包。。faint。。经测试题目的数据可能达到0.00001,甚至比0.00001还小,,所以必须转换思路,,
于是转成以所有银行的总资产为背包容量V。。求最大的逃跑概率。。
注意:题目给我们的是被抓的概率,,而我们要求最大的逃跑率,需要去被抓的概率pi的补 ,即1-pi
只有逃跑率才会等于各个逃跑率之积,被抓的概率不会等于各个被抓的概率之积,,概率的知识,不多说。。
状态转移方程:dp[j] = max ( dp[j], dp[j-cost[i]] * weight[i])
double dp[10005]; int money[105]; double pj[105]; int main(){ int t,kase=0; cin>>t; while(t--){ kase++; double p; int n; scanf("%lf%d",&p,&n); p=1-p; int sum=0; memset(dp,0,sizeof(dp)); for(int i=0;i<n;i++){ double pp; scanf("%d%lf",&money[i],&pp); pj[i]=1-pp; sum+=money[i]; } dp[0]=1; for(int i=0;i<n;i++){ for(int j=sum;j>=money[i];j--) dp[j]=max(dp[j],dp[j-money[i]]*pj[i]); } for(int i=sum;i>=0;i--){ if(dp[i]>=p){ printf("%d\n",i); break; } } } return 0; }HDU1864:由于报销额是double型,所以我们把发票作为背包,对于每个发票,在可以选择报销或者不报销。dp[j]=max(dp[j],dp[j-1]+money[i]);就是说可以,报销J个发票所得到的最大经费,可以第j个是报销的,也可以是第j个不报销而最大经费是由前j-1个发票加上另外第i个发票的报销数额。。
double a[35]; double p[35]; int main(){ double q; int n; while(scanf("%lf%d",&q,&n)&&n){ int m; memset(a,0,sizeof(a)); int count=0; for(int i=0;i<n;i++){ scanf("%d",&m); int flag=0; double A=0,B=0,C=0; for(int j=0;j<m;j++){ char c,d; double val; cin>>c>>d>>val; if(c=='A'||c=='B'||c=='C'){ if(val>600){ flag=1; continue; } if(c=='A') A+=val; else if(c=='B') B+=val; else C+=val; } else{ flag=1; continue; } } if(!flag&&A<=600&&B<=600&&C<=600&&A+B+C<=1000) p[count++]=A+B+C; } for(int i=0;i<count;i++){ for(int j=count;j>=1;j--){ if(a[j-1]+p[i]<=q) a[j]=max(a[j],a[j-1]+p[i]); } } double maxn=0; for(int i=1;i<=count;i++) if(a[i]>maxn) maxn=a[i]; printf("%.2lf\n",maxn); } return 0; }
int a[2005]; int dp[2005][1005]; int main(){ int n,k; while(cin>>n>>k){ for(int i=1;i<=n;i++) scanf("%d",&a[i]); sort(a+1,a+n+1); memset(dp,0,sizeof(dp)); for(int i=2;i<=n;i++){ for(int j=1;j<=i/2;j++){ if(i==2*j) dp[i][j]=dp[i-2][j-1]+(a[i]-a[i-1])*(a[i]-a[i-1]); else dp[i][j]=min(dp[i-1][j],dp[i-2][j-1]+(a[i]-a[i-1])*(a[i]-a[i-1])); } } printf("%d\n",dp[n][k]); } return 0; }