洛谷P2280 [HNOI2003]激光炸弹
题目描述
输入输出格式
输入格式:
输入文件名为input.txt
输入文件的第一行为正整数n和正整数R,接下来的n行每行有3个正整数,分别表示 xi,yi ,vi 。
输出格式:
输出文件名为output.txt
输出文件仅有一个正整数,表示一颗炸弹最多能炸掉地图上总价值为多少的目标(结果不会超过32767)。
输入输出样例
输入样例#1:
2 1 0 0 1 1 1 1
输出样例#1:
30分 前缀和(写的丑的后果TLE+WA)
100分 标准的前缀和
1
#include<iostream> #include<cstdio> using namespace std; int sum[6010][6010],dp[6010][6010],ans,map[6010][6010],cnt[6010]; int n,r,max_x,max_y; int main(){ //freopen("Cola.txt","r",stdin); scanf("%d%d",&n,&r); int x,y,z; for(int i=1;i<=n;i++){ scanf("%d%d%d",&x,&y,&z); max_x=max(max_x,x); max_y=max(max_y,y); map[x][y]=z; } for(int i=0;i<=max_y;i++) for(int j=0;j<=r-1;j++) sum[0][i]+=map[j][i]; for(int i=0;i<=max_y;i++){ for(int j=1;j<=max_x;j++){ sum[j][i]=sum[j-1][i]-map[j-1][i]+map[j+r-1][i]; } } for(int i=0;i<=r-1;i++) dp[0][0]+=sum[0][i]; ans=max(ans,dp[0][0]); for(int i=0;i<=r-1;i++){ for(int j=0;j<=r-1;j++){ cnt[i]+=map[i][j]; } } for(int i=1;i<=max_x;i++){ for(int j=0;j<=r-1;j++) cnt[i+r-1]+=map[i+r-1][j]; dp[i][0]=dp[i-1][0]-cnt[i-1]+cnt[i+r-1]; ans=max(ans,dp[i][0]); } for(int i=1;i<=max_y;i++) for(int j=0;j<=max_x;j++){ dp[j][i]=dp[j][i-1]-sum[j][i-1]+sum[j][i+r-1]; ans=max(ans,dp[i][j]); } printf("%d",ans); } 30分 前缀和
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; int n,r,dp[5101][5101]; void read(int &n) { char c='+';int x=0;bool flag=0; while(c<'0'||c>'9'){c=getchar();if(c=='-')flag=1;} while(c>='0'&&c<='9') {x=x*10+c-48;c=getchar();} flag==1?n=-x:n=x; } int ans=0; int main() { read(n);read(r); for(int i=1;i<=n;i++) { int x,y,z; read(x);read(y);read(z); dp[x+1][y+1]=z; } for(int i=1;i<=5001;i++) for(int j=1;j<=5001;j++) dp[i][j]=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]+dp[i][j]; for(int i=0;i<=5001-r;i++) for(int j=0;j<=5001-r;j++) ans=max(ans,dp[i+r][j+r]-dp[i+r][j]-dp[i][j+r]+dp[i][j]); printf("%d",ans); return 0; }