HDU 5045 DP+狀壓,hdu5045dp
2014 ACM/ICPC Asia Regional Shanghai Online
給出N個人做M道題的正確率,每道題只能由一個人做出,並且當所有人都做出來且僅做出一道題時,做過題的人才可以繼續做題,求最大期望。
一共只有10個人,狀壓儲存每個人是否已經做出題目,如果都作出則狀態清0;
#include "stdio.h"#include "string.h"double Max(double a,double b){if (a<b) return b;else return a;}double ans,dp[1010][1050],a[1010][1010];int main(){int Case,ii,i,j,aim,k,n,m,peo;scanf("%d",&Case);for (ii=1;ii<=Case;ii++){scanf("%d%d",&n,&m);for (i=1;i<=n;i++)for (j=1;j<=m;j++)scanf("%lf",&a[i][j]);printf("Case #%d: ",ii);aim=(1<<n)-1;for (i=0;i<=m;i++)for (j=0;j<=aim;j++)dp[i][j]=-1;dp[0][0]=0;for (j=1;j<=m;j++)for (i=0;i<=aim;i++)if (dp[j-1][i]!=-1)for (k=1;k<=n;k++){peo=1<<(k-1);if ((i&peo)==peo) continue;peo|=i;if (peo==aim) peo=0;dp[j][peo]=Max(dp[j][peo],dp[j-1][i]+a[k][j]);}ans=0;for (i=0;i<=aim;i++)ans=Max(ans,dp[m][i]);printf("%.5lf\n",ans);}}
HDU3646 DP解為何WA?
注意考慮M>N 的情況!還有0鳥0怪的邊界!
#include<iostream>
using namespace std;
const int NN = 11000;
int mn(int x,int y){if(x<y)return x;return y;}
int f[NN][102],g[NN][102],b[NN],ksum[NN*10];
int main()
{
//freopen("in.txt","r",stdin);
int pt,i,j,x,N,M,K,gg,tgg,ed,ted;
while(scanf("%d%d%d",&N,&M,&K),N+M+K){
for(i=1;i<=N;i++){
scanf("%d",&x);b[i]=x;
}
for(ksum[0]=0,i=1;i<=K;i++){
scanf("%d",&x);
ksum[i]=ksum[i-1]+x;
}
f[0][0]=g[0][0]=0;
for(i=1;i<=N;i++){
for(j=0;j<=mn(i,M);j++){
ed=ted=-1;
if(j-1>=0&&i-1>=j-1){
int st=f[i-1][j-1];
pt=b[i]*2+g[i-1][j-1];
ed=st;
while(ed+1<=K&&ksum[ed+1]<=pt){
ed++;
if(ksum[ed]==pt)break;
}
if(ed==st){
gg=pt;
}else gg=ksum[ed];
}
if(i-1>=j){
int st=f[i-1][j];
pt=b[i]+g[i-1][j];
ted=st;
while(ted+1<=K&&ksum[ted+1]<=pt){
ted++;
if(ksum[ted]==pt)break;
}
if(ted==st){
tgg=pt;
}else tgg=ksum[ted];
}
if(ted>ed||(ted==ed&&tgg>gg)){gg=tgg,ed=ted;}
f[i][j]=ed;g[i][j]=gg;
//printf("%d ",f[i][j]);
}//printf("\n");
}//printf("\n");
for(j=-1,i=0;i<=M;i++)if(j<f[N][i])j=f[N][i];
printf("%d\n",j);
}
return 0;
}...餘下全文>>
HDU 1074 怎做 ,聽說是一個狀態壓縮DP 牛神們給講講
bvbcbcvbv