tozangezan's diary

勝手にソースコードをコピペして利用しないでください。

PKU1036 Gangsters

久しぶりにPKUを解いてみたwww

1036:Gangsters
dp[i][j]:時刻iで開き方jのときの求めるものの和の最大値
で通らない。
正攻法はdp[i%2][j]を使う。
間違った方法はdpの配列をintではなくshort intでとる
(3000000の配列でメモリ制限10MB、なおかつ答えは高々30000なので)

#include<stdio.h>
#include<math.h>
#include<algorithm>
using namespace std;
int t[100];
int p[100];
int s[100];
short int dp[30001][101];
int main(){
	int a,b,c;
	scanf("%d%d%d",&a,&b,&c);
	for(int i=0;i<a;i++)scanf("%d",t+i);
	for(int i=0;i<a;i++)scanf("%d",p+i);
	for(int i=0;i<a;i++)scanf("%d",s+i);
	for(int i=0;i<a;i++){
		if(t[i]==0&&s[i]==0)dp[0][s[i]]+=p[i];
	}
	for(int i=1;i<=c;i++){
		dp[i][0]=max(dp[i-1][0],dp[i-1][1]);
	//	printf("%d ",dp[i][0]);
		for(int j=1;j<b;j++){
			dp[i][j]=max(dp[i-1][j],max(dp[i-1][j+1],dp[i-1][j-1]));
		//	printf("%d ",dp[i][j]);
		}
		
		dp[i][b]=max(dp[i-1][b-1],dp[i-1][b]);
	//	printf("%d\n",dp[i][b]);
		for(int j=0;j<a;j++){
			if(t[j]==i&&i>=s[j])dp[i][s[j]]+=p[j];
		}
	}
	short int ret=0;
	for(int i=0;i<b+1;i++)ret=max(ret,dp[c][i]);
	printf("%d\n",ret);
}