dp水题,状态很容易想到,dp[ i ] 表示机器人到达第i个点的最小花费,然后O(n)的时间状态转移
这个纠结很久的题目终于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;
}
H题代码
#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;
}