hdu 4281 judges' response

来源:互联网 发布:郑州黑马程序员官网 编辑:程序博客网 时间:2024/05/29 15:40

hdu 4281 judges' response

这个题比赛的时候没有搞出来,当时思路太乱了,而且样例都没仔细看,就开始敲了,导致敲完了看样例才发现题意理解错了,T_T


问1: 抽象成给你n(你<=15)个物品 (物品的体积为C[ i ]) ,问至少用几个箱子把这n个物品装满

问2: 预处理出一个人在服务时间小于等于m的情况下,服务集合为state 的最短行走距离,然后就和问1一样背包就行了


#include<stdio.h>#include<string.h>#include<iostream>#include<queue>#include<cmath>using namespace std;int d[16][16],c[16],n,m;int dp1[1<<16],dp2[1<<16],x[16],y[16];int ans[1<<16],sum[1<<16],dp[1<<16][16];bool vis[1<<16][16];int solve1(){    dp1[0]=0;    for(int i=1;i<(1<<n);i++)    {        int tmp=0;        for(int j=0;j<n;j++)          if(i&(1<<j)) tmp+=c[j];        if(tmp<=m) dp1[i]=1;        else dp1[i]=-1;    }    int lim=(1<<n)-1;    for(int i=0;i<(1<<n);i++)       if(dp1[i]>=0){           int sub=i^lim;           for(int j=sub;j;j=(j-1)&(sub))             if(dp1[j]>=0){                if(dp1[i|j]==-1||dp1[i|j]>dp1[i]+dp1[j]) dp1[i|j]=dp1[i]+dp1[j];             }       }    return dp1[lim];}int solve2(){    memset(sum,0,sizeof(sum));    for(int i=1;i<(1<<n);i++)    for(int j=0;j<n;j++)       if(i&(1<<j)) sum[i]+=c[j];    queue<pair<int,int> > q;    q.push(make_pair(0,0));    memset(vis,0,sizeof(vis));    memset(dp,-1,sizeof(dp));    dp[0][0]=c[0];    for(;!q.empty();q.pop())    {        int s=q.front().first,u=q.front().second;        vis[s][u]=0;        for(int j=0;j<n;j++)          if(!(s&(1<<j))&&sum[s|(1<<j)]<=m){               if(dp[s|(1<<j)][j]==-1||dp[s|(1<<j)][j]>dp[s][u]+d[u][j]){                  dp[s|(1<<j)][j]=dp[s][u]+d[u][j];                  if(!vis[s|(1<<j)][j]) q.push(make_pair(s|(1<<j),j)),vis[s|(1<<j)][j]=1;               }          }    }    memset(ans,-1,sizeof(ans));    for(int i=0;i<(1<<n);i++)    for(int j=0;j<n;j++)      if(dp[i][j]!=-1){         if(ans[i]==-1||ans[i]>dp[i][j]+d[j][0]) ans[i]=dp[i][j]+d[j][0];      }    ans[0]=0;    int lim=(1<<n)-1;    for(int i=0;i<(1<<n);i++)    if(ans[i]>=0)    {        int sub=lim^i;        for(int j=sub;j;j=(j-1)&(sub))         if(ans[j]>=0){           if(ans[i|j]==-1||ans[i|j]>ans[i]+ans[j]) ans[i|j]=ans[i]+ans[j];         }    }    return ans[lim];}int main(){    while(scanf("%d%d",&n,&m)==2)    {        for(int i=0;i<n;i++) scanf("%d%d",&x[i],&y[i]);        for(int i=0;i<n;i++) scanf("%d",&c[i]);        for(int i=0;i<n;i++)        for(int j=0;j<n;j++) d[i][j]=ceil(sqrt((x[i]-x[j])*(x[i]-x[j])*1.0+(y[i]-y[j])*(y[i]-y[j])*1.0));        int i;        for(i=0;i<n;i++)          if(c[i]>m) break;        if(i<n){           printf("-1 -1\n");        }else printf("%d %d\n",solve1(),solve2());    }    return 0;}


原创粉丝点击