0120:Patisserie
問題文
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0120
ビットDPで解いた。
dp[ すでに置いたケーキ ][ ケーキの番号 ] := 横幅
countは立っているビットの数を数える関数。
#include<iostream> #include<vector> #include<string> #include<cstdio> #include<cmath> #include<algorithm> #include<climits> #include<cfloat> #include<sstream> #define INF (1<<29) using namespace std; double dist(double p,double q){ double a=p+q,b=abs(p-q); return sqrt(a*a-b*b); } int count(int bits){ bits = (bits & 0x55555555) + (bits >> 1 & 0x55555555); bits = (bits & 0x33333333) + (bits >> 2 & 0x33333333); bits =(((bits >> 4) + bits) & 0x0f0f0f0f); bits += bits >> 8; return (bits + (bits >> 16)) & 0xff; } double dp[(1<<12)][12]; int main(void){ string str; while(getline(cin,str)){ int value; stringstream ss(str); vector<double>in; while(ss >> value)in.push_back(value); if(in.size()<1)break; double L=in[0]; int m=in.size()-1; vector<double>p(m); for(int i=1;i<in.size();i++)p[i-1]=in[i]; fill(dp[0],dp[1<<12],INF); for(int i=0;i<m;i++)dp[1<<i][i]=p[i]; for(int S=0;S<(1<<m);S++){ for(int v=0;v<m;v++){ for(int u=0;u<m;u++){ if(S>>u&1 || !(S>>v&1))continue; int nx=S; nx|=(1<<u); if(count(S)==m-1)dp[nx][u]=min(dp[nx][u],dp[S][v]+dist(p[v],p[u])+p[u]); else dp[nx][u]=min(dp[nx][u],dp[S][v]+dist(p[v],p[u])); } } } double ans=INF; for(int i=0;i<m;i++)ans=min(ans,dp[(1<<m)-1][i]); if(ans<=L)cout << "OK" << endl; else cout << "NA" << endl; } return 0; }