Problem B: Robot Challenge
dp水题,状态很容易想到,dp[ i ] 表示机器人到达第i个点的最小花费,然后O(n)的时间状态转移
poj Problem H: Ideal Path
这个纠结很久的题目终于ac了,蛋疼无限呀!!!
肯定有比我好的方法,我是纪录每个节点的前两种颜色,然后对于每一层开始排序,然后再重新分配大小关系……感觉好麻烦,肯定有比我好的方法,感觉我这个方法实在是太土了
B题代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> using namespace std; const int inf=0x3fffffff; const int maxn=1010; double dp[maxn],sum[maxn],x[maxn],y[maxn],p[maxn]; double dis[maxn][maxn]; int main() { int n; while(scanf("%d",&n)==1&&n) { for(int i=1;i<=n;i++) scanf("%lf%lf%lf",&x[i],&y[i],&p[i]),sum[i]=sum[i-1]+p[i]; x[n+1]=100; y[n+1]=100; p[0]=0; sum[n+1]=sum[n]; n++; for(int i=0;i<=n;i++) for(int j=i+1;j<=n;j++) dis[i][j]=sqrt((x[j]-x[i])*1.0*(x[j]-x[i])+(y[j]-y[i])*1.0*(y[j]-y[i])); fill(dp,dp+n+1,inf); dp[0]=0; //cout<<dis[0][1]<<endl; for(int i=1;i<=n;i++) { for(int j=0;j<i;j++) dp[i]=min(dp[i],dp[j]+sum[i-1]-sum[j]+1.0+dis[j][i]); } printf("%.3lf\n",dp[n]); } return 0; }
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <string> #include <queue> using namespace std; const int maxn=500010; const int maxe=1000010; const int inf=0x3fffffff; int var[maxe],next[maxe]; int col[maxe]; int h[maxn],dp[maxn],tot,n,m,tmp[maxn],pre[maxn],from[maxn],val[maxn]; bool vis[maxn]; long long ss[maxn][2]; int que[5000010]; void add(int u,int v,int c) { from[tot]=u,var[tot]=v,col[tot]=c,next[tot]=h[u],h[u]=tot++; } int cmp(int a,int b,int c,int d) { if(a>c) return 0; if(a==c&&b>=d) return 0; return 1; } int cmp1(int a,int b) { return !cmp(ss[b][0],ss[b][1],ss[a][0],ss[a][1]); } bool equal(int a,int b) { return ss[a][0]==ss[b][0]&&ss[a][1]==ss[b][1]; } void bfs() { memset(vis,0,sizeof(vis)); dp[1]=0; ss[1][0]=0; int next_level=1,l=0,r=0; que[r++]=1; pre[1]=0; while(l<r) { int cur=que[l]; vis[cur]=1; if(dp[cur]==next_level) { int num=0; for(int i=l;i<r;i++) tmp[num++]=que[i]; sort(tmp,tmp+num,cmp1); int cnt=1; val[0]=1; for(int i=1;i<num;i++) if(equal(tmp[i-1],tmp[i])) val[i]=cnt; else val[i]=++cnt; for(int i=0;i<num;i++) ss[tmp[i]][0]=val[i],ss[tmp[i]][1]=0; next_level++; } l++; for(int i=h[cur];i!=-1;i=next[i]) { int v=var[i]; if(dp[v]>dp[cur]+1||((dp[v]==dp[cur]+1)&&cmp(ss[cur][0],col[i],ss[v][0],ss[v][1]))) { dp[v]=dp[cur]+1; ss[v][0]=ss[cur][0]; ss[v][1]=col[i]; pre[v]=i; if(!vis[v]) vis[v]=1,que[r++]=v; } } } } int main() { int a,b,c; while(scanf("%d%d",&n,&m)==2) { tot=0; memset(h,-1,sizeof(h)); for(int i=0;i<m;i++) { scanf("%d%d%d",&a,&b,&c); add(a,b,c); add(b,a,c); } fill(dp,dp+n+1,inf); bfs(); int sz=dp[n]; printf("%d\n",sz); vector<int> path; int nw=n; for(int i=0;i<sz;i++) { nw=pre[nw]; path.push_back(col[nw]); nw=from[nw]; } printf("%d",path[sz-1]); for(int i=sz-2;i>=0;i--) printf(" %d",path[i]); puts(""); } return 0; }