程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> HDU 4281 Judges response(12年天津 MTSP問題)

HDU 4281 Judges response(12年天津 MTSP問題)

編輯:C++入門知識

題目:給出N個人,其中0號是裁判的位置,剩下有N-1的人提問,裁判需要去回答問題,每個人有一個val,每個裁判能拿到的val的上限為K。問題最少需要幾個裁判,以及最少時間

 


第一問可以狀態壓縮DP解決,dp[i]表示狀態i需要幾個裁判,也可以排序之後貪心。從大到小,盡可能地裝入一個盒子。

第二問就是多個TSP問題,dp[i][j]表示當前位置 在i,可行狀態為j的最小費用,best[i]表示對於狀態i的最小費用(而且是一個完整狀態,裁判都回到原點),因為之前TSP中是求的可行狀態,也就是每個裁判的上限不能超過K。之後就是枚舉所有狀態,對於一個狀態,枚舉他的所有子集,見代碼中的位運算部分。而且兩個子集中必須要包含0號結點,因為每個裁判都是從0出發的

 
[cpp]
#include<iostream>  
#include<cstdio>  
#include<map>  
#include<cstring>  
#include<cmath>  
#include<vector>  
#include<algorithm>  
#include<set>  
#define inf 1<<28  
#define M 100005  
#define N 55  
#define Min(a,b) ((a)<(b)?(a):(b))  
#define Max(a,b) ((a)>(b)?(a):(b))  
#define pb(a) push_back(a)  
#define mem(a,b) memset(a,b,sizeof(a))  
#define LL long long  
#define MOD 1000000007  
using namespace std; 
struct Point{ 
    int x,y; 
}p[20]; 
int n,m,val[20],path[20][20]; 
int dp[16][1<<16]; 
int best[1<<16],ok[1<<16]; 
int dist(Point p1,Point p2){ 
    return ceil(sqrt((double)(p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y))); 

void Get_dist(){ 
    for(int i=0;i<n;i++) for(int j=0;j<n;j++) path[i][j]=dist(p[i],p[j]); 

void Init(){ 
    for(int i=0;i<n;i++) 
        for(int j=0;j<(1<<n);j++) 
            dp[i][j]=inf; 
    for(int i=0;i<(1<<n);i++) 
        best[i]=inf; 
    dp[0][1]=0; 

int check(int state){ 
    int sum=0; 
    for(int i=0;i<n;i++) 
        if(state&(1<<i)) 
            sum+=val[i]; 
    return sum<=m; 

bool cmp(int a,int b){return a>b;} 
int slove(){ 
    int v[20]; 
    memcpy(v,val,sizeof(val)); 
    sort(v,v+n,cmp); 
    if(v[0]>m) return -1; 
    int flag[20]; 
    mem(flag,0); 
    int cnt=0; 
    for(int i=0;i<n;i++){ 
        if(flag[i]) continue; 
        int tmp=0;   
        for(int j=i;j<n;j++){ 
            if(flag[j]==0){ 
                if(tmp+v[j]<=m){ 
                    flag[j]=1; 
                    tmp+=v[j]; 
                } 
            } 
        } 
        cnt++; 
    } 
    return cnt; 

int TSP(){ 
    for(int i=0;i<(1<<n);i++){ 
        if(ok[i]) 
            for(int j=0;j<n;j++) 
                if(i&(1<<j)){ 
                    best[i]=min(best[i],dp[j][i]+path[j][0]); 
                    for(int k=0;k<n;k++) 
                        if(!(i&(1<<k))) 
                            dp[k][i|(1<<k)]=min(dp[k][i|(1<<k)],dp[j][i]+path[j][k]); 
                } 
    } 
    for(int i=0;i<(1<<n);i++) 
        if(i&1) 
            for(int j=i&(i-1);j;j=i&(j-1)) 
                best[i]=min(best[i],best[j]+best[(i-j)|1]); 
    return best[(1<<n)-1]; 

 
int main(){ 
    while(scanf("%d%d",&n,&m)!=EOF){ 
        for(int i=0;i<n;i++) scanf("%d%d",&p[i].x,&p[i].y); 
        for(int i=0;i<n;i++) scanf("%d",&val[i]); 
        for(int i=0;i<(1<<n);i++)  ok[i]=check(i); 
        Get_dist(); 
        Init(); 
        int ans1=slove(); 
        if(ans1==-1) {printf("-1 -1\n");continue;} 
        printf("%d %d\n",ans1,TSP()); 
    } 
    return 0; 

#include<iostream>
#include<cstdio>
#include<map>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
#include<set>
#define inf 1<<28
#define M 100005
#define N 55
#define Min(a,b) ((a)<(b)?(a):(b))
#define Max(a,b) ((a)>(b)?(a):(b))
#define pb(a) push_back(a)
#define mem(a,b) memset(a,b,sizeof(a))
#define LL long long
#define MOD 1000000007
using namespace std;
struct Point{
 int x,y;
}p[20];
int n,m,val[20],path[20][20];
int dp[16][1<<16];
int best[1<<16],ok[1<<16];
int dist(Point p1,Point p2){
 return ceil(sqrt((double)(p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)));
}
void Get_dist(){
 for(int i=0;i<n;i++) for(int j=0;j<n;j++) path[i][j]=dist(p[i],p[j]);
}
void Init(){
 for(int i=0;i<n;i++)
  for(int j=0;j<(1<<n);j++)
   dp[i][j]=inf;
 for(int i=0;i<(1<<n);i++)
  best[i]=inf;
 dp[0][1]=0;
}
int check(int state){
 int sum=0;
 for(int i=0;i<n;i++)
  if(state&(1<<i))
   sum+=val[i];
 return sum<=m;
}
bool cmp(int a,int b){return a>b;}
int slove(){
 int v[20];
 memcpy(v,val,sizeof(val));
 sort(v,v+n,cmp);
 if(v[0]>m) return -1;
 int flag[20];
 mem(flag,0);
 int cnt=0;
 for(int i=0;i<n;i++){
  if(flag[i]) continue;
  int tmp=0; 
  for(int j=i;j<n;j++){
   if(flag[j]==0){
    if(tmp+v[j]<=m){
     flag[j]=1;
     tmp+=v[j];
    }
   }
  }
  cnt++;
 }
 return cnt;
}
int TSP(){
 for(int i=0;i<(1<<n);i++){
  if(ok[i])
   for(int j=0;j<n;j++)
    if(i&(1<<j)){
     best[i]=min(best[i],dp[j][i]+path[j][0]);
     for(int k=0;k<n;k++)
      if(!(i&(1<<k)))
       dp[k][i|(1<<k)]=min(dp[k][i|(1<<k)],dp[j][i]+path[j][k]);
    }
 }
 for(int i=0;i<(1<<n);i++)
  if(i&1)  www.2cto.com
   for(int j=i&(i-1);j;j=i&(j-1))
    best[i]=min(best[i],best[j]+best[(i-j)|1]);
 return best[(1<<n)-1];
}

int main(){
 while(scanf("%d%d",&n,&m)!=EOF){
  for(int i=0;i<n;i++) scanf("%d%d",&p[i].x,&p[i].y);
  for(int i=0;i<n;i++) scanf("%d",&val[i]);
  for(int i=0;i<(1<<n);i++)  ok[i]=check(i);
  Get_dist();
  Init();
  int ans1=slove();
  if(ans1==-1) {printf("-1 -1\n");continue;}
  printf("%d %d\n",ans1,TSP());
 }
 return 0;
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved