试题 F: 费用报销
思路:将月日转化成这一年的第几天,然后进行DP
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
const int N = 1010, M = 5010;
PII f[N];
int dp[N][M];
int month[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int get(int m,int day)
{
int ans=0;
for(int i=1;i<m;i++)
ans+=month[i];
return ans+day;
}
signed main()
{
IOS
int n,m,k;cin>>n>>m>>k;
for(int i=1;i<=n;i++)
{
int a,b;cin>>a>>b>>f[i].second;
f[i].first=get(a,b);
}
sort(f+1,f+n+1);
f[0].first=-100;
dp[0][0]=1;
int cnt=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
dp[i][j]=max(dp[i][j],dp[i-1][j]);
while(cnt<i && f[i].first-f[cnt].first>=k) cnt++;
while(cnt>0 && f[i].first-f[cnt].first<k) cnt--;
if(j>=f[i].second)
dp[i][j]=max(dp[i][j],dp[cnt][j-f[i].second]+f[i].second);
}
cout<<dp[n][m];
return 0;
}