题目链接:http://acdream.info/problem?pid=1092
题解:
基础dp,首先要根据每个地鼠出现的时间对他们排序,然后就可以递推,递归(记忆化搜索)。
递推:
Status | Accepted |
---|---|
Time | 308ms |
Memory | 1716kB |
Length | 1086 |
Lang | C++ |
Submitted | 2017-03-24 19:00:04 |
Shared | |
RemoteRunId | 99339 |
#include<iostream>//ACdream - 1092 dp 递推
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define MAX(a,b) (a>b?a:b)
using namespace std;
typedef long long LL;
int n,v;
double dp[1005], ans;
struct node
{
int x,y,t;
double r;
}m[1005];
bool cmp(node a, node b)
{
return a.t<b.t;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&v);
for(int i = 0; i<n; i++)
scanf("%d%d%d%lf",&m[i].x, &m[i].y, &m[i].t,&m[i].r );
sort(m,m+n,cmp);
ans = 0;
memset(dp,0,sizeof(dp));
for(int i = 0; i<n; i++)
{
dp[i] = m[i].r;
for(int j = 0; j<i; j++)
{
double dis1 = sqrt( (m[i].x-m[j].x)*(m[i].x-m[j].x) + (m[i].y-m[j].y)*(m[i].y-m[j].y) );
double dis2 = 1.0*v*(m[i].t-m[j].t);
if(dis2>=dis1)
dp[i] = MAX(dp[i],m[i].r+dp[j]);
}
ans = MAX(dp[i],ans);
}
printf("%.6lf\n",ans);
}
return 0;
}
递归(正向,跟递推一样)
Status | Accepted |
---|---|
Time | 380ms |
Memory | 1716kB |
Length | 1109 |
Lang | C++ |
Submitted | 2017-03-24 18:56:00 |
Shared | |
RemoteRunId | 99338 |
#include<iostream>//ACdream - 1092
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define MAX(a,b) (a>b?a:b)
using namespace std;
typedef long long LL;
int n,v;
double dp[1005], ans;
struct node
{
int x,y,t;
double r;
}m[1005];
bool cmp(node a, node b)
{
return a.t<b.t;
}
double dfs(int k)
{
if(dp[k]) return dp[k];
dp[k] = m[k].r;
for(int i = 0; i<k; i++)
{
double dis1 = sqrt( (m[k].x-m[i].x)*(m[k].x-m[i].x) + (m[k].y-m[i].y)*(m[k].y-m[i].y) );
double dis2 = 1.0*v*(m[k].t-m[i].t);
if(dis2>=dis1)
dp[k] = MAX(dp[k],dfs(i)+m[k].r);
}
return dp[k];
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&v);
for(int i = 0; i<n; i++)
scanf("%d%d%d%lf",&m[i].x, &m[i].y, &m[i].t,&m[i].r );
sort(m,m+n,cmp);
ans = 0;
memset(dp,0,sizeof(dp));
for(int i = 0; i<n; i++)
{
ans = MAX(ans,dfs(i));
}
printf("%.6lf\n",ans);
}
}
递归(反向):
Status | Accepted |
---|---|
Time | 328ms |
Memory | 1716kB |
Length | 1236 |
Lang | C++ |
Submitted | 2017-03-24 18:54:43 |
Shared | |
RemoteRunId | 99337 |
#include<iostream>//ACdream - 1092 dp 递归
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define MAX(a,b) (a>b?a:b)
using namespace std;
typedef long long LL;
int n,v;
double dp[1005], ans;
struct node
{
int x,y,t;
double r;
}m[1005];
bool cmp(node a, node b)
{
return a.t<b.t;
}
double dfs(int k)
{
if(dp[k]) return dp[k];
dp[k] = m[k].r;
for(int i = k+1; i<n; i++)
{
double dis1 = sqrt( (m[k].x-m[i].x)*(m[k].x-m[i].x) + (m[k].y-m[i].y)*(m[k].y-m[i].y) );
double dis2 = 1.0*v*(m[i].t-m[k].t);
if(dis2>=dis1)
dp[k] = MAX(dp[k],dfs(i)+m[k].r);
}
return dp[k];
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&v);
for(int i = 0; i<n; i++)
scanf("%d%d%d%lf",&m[i].x, &m[i].y, &m[i].t,&m[i].r );
sort(m,m+n,cmp);
ans = 0;
memset(dp,0,sizeof(dp));
for(int i = 0; i<n; i++)
{
if(!dp[i])
ans = MAX(ans,dfs(i));
}
printf("%.6lf\n",ans);
}
}