狀態定義很顯然的DP題
設dp[i][j]爲第i秒位於位置j所能獲得的最大禮物價值
這樣dp[i][j]可以由dp[i - 1][j - 1],dp[i - 1][j],dp[i - 1][j + 1]推來
一開始怎麼交怎麼wa,鬱悶不已
然後發現是這句話:
當禮物在某一秒末恰好到達小杉所在的格子中,小杉就接到了這個禮物
所以。。所有到達時間是浮點數(速度不被H整除)的禮物都是接不到的……
改了就A了……
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 2000 + 50;
int W,P,H,N;
struct zt{
int t,r,v,s;
int arr;
}l[MAXN << 1],e[MAXN << 1];
int dp[2500][550];
int last;
bool cmp(zt a,zt b){
return a.arr < b.arr;
}
int ans1,ans,cnt;
int main(){
scanf("%d%d%d%d",&W,&P,&H,&N);
for(int i = 1;i <= N;i ++){
scanf("%d%d%d%d",&e[i].t,&e[i].r,&e[i].v,&e[i].s);
e[i].arr = e[i].t + H/e[i].v;
if(H%e[i].v || e[i].arr < abs(e[i].r - P)){
ans1 += e[i].s;
}
else{
cnt ++;
l[cnt] = e[i];
last = max(last,l[cnt].arr);
}
}
N = cnt;
sort(l + 1,l + N + 1,cmp);
memset(dp,-1,sizeof(dp));
dp[0][P] = 0;
int p = 1;
for(int t = 1;t <= last;t ++){
int v = 0;
loop:
if(t == l[p].arr){
v = l[p].s;
}
for(int j = 1;j <= W;j ++){
if(j != 1 && dp[t - 1][j - 1] != -1){
dp[t][j] = max(dp[t][j],dp[t - 1][j - 1] + (j == l[p].r)*v);
}
if(j != W && dp[t - 1][j + 1] != -1){
dp[t][j] = max(dp[t][j],dp[t - 1][j + 1] + (j == l[p].r)*v);
}
if(dp[t - 1][j] != -1){
dp[t][j] = max(dp[t][j],dp[t - 1][j] + (j == l[p].r)*v);
}
ans = max(ans,dp[t][j]);
}
if(v)p ++;
if(l[p].arr == l[p - 1].arr)goto loop;
}
printf("%d\n%d",ans,ans1);
}
其實有bug,看了題解才意識到
goto是爲了處理同一時刻落下的禮物情況;
但是當同一時刻到達同一位置的禮物不止一個的時候,這個程序只能選擇一個;
處理方法是開數組V[i][j],表示i時刻到達位置j的禮物的價值總和
連goto都免了……
處理後代碼:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int dp[2500][550],V[2500][550];
int a,b,c,d;
int W,P,H,N;
int ans1,ans2,cnt,last;
int main(){
scanf("%d%d%d%d",&W,&P,&H,&N);
for(int i = 1;i <= N;i ++){
scanf("%d%d%d%d",&a,&b,&c,&d);
if(H%c || a + H/c < abs(b - P))
ans2 += d;
else
V[a + H/c][b] += d,last = max(last,a + H/c);
}
memset(dp,-1,sizeof(dp));
dp[0][P] = 0;
for(int i = 1;i <= last;i ++)
for(int j = 1;j <= W;j ++){
dp[i][j] = max(max(dp[i - 1][j - 1],dp[i - 1][j + 1]),max(dp[i - 1][j],dp[i][j])) + V[i][j];
ans1 = max(ans1,dp[i][j]);
}
printf("%d\n%d",ans1,ans2);
return 0;
}