C.操作数组
分析:
将a,b数组转换为c数组(c=a-b),之后对于c数组的总和,每次操作的增值为0,也就是只有c数组中正值等于负值时是可以转换的,而正值总和即为答案,否则应该输出-1;
#include<bits/stdc++.h>
using namespace std;
int n,a[100001],b[100001];
long long z,f;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=n;i++){
cin>>b[i],a[i]-=b[i];
if(a[i]>=0)
z+=a[i];
else
f-=a[i];
}
if(z!=f)
cout<<"-1\n";
else
cout<<z;
}
D.遗迹探险(线性DP)
其实是一个比较简单的线性DP,但是宝箱的价值可能为负,Debug了半天;
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
int n,m;
pair<int,int> c[10];//传送门坐标
long long f[1001][1001],ff[1001][1001];
//f[i][j]表示从i,j到n,m能得到宝箱的价值的最大总和
//f[i][j]=max(f[i+1][j],f[i][j+1])+a[i][j];
//ff[i][j]表示从1,1到i,j能得到宝箱的价值最大总和
//ff[i][j]=max(ff[i-1][j],ff[i][j-1])+a[i][j];
long long a[1001][1001];
void solve() {
int k,x,y;
cin>>k;
for(int i=1; i<=k; i++)
cin>>x>>y,c[i]= {x,y};
long long mx=f[1][1];//不传送的情况下得到的最大价值
for(int i=1; i<=k; i++)
for(int j=1; j<=k; j++) {//遍历每个传送门
if(i==j)
continue;
mx=max(ff[c[i].fi][c[i].se]+f[c[j].fi][c[j].se],mx);
//从c[i]传送到c[j]传送门时的最大价值
}
cout<<mx<<"\n";
}
int main() {
cin>>n>>m;
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
cin>>a[i][j];
for(int i=0; i<=n+1; i++)
for(int j=0; j<=m+1; j++)
f[i][j]=ff[i][j]=-1e10;
for(int i=n; i>=1; i--)
for(int j=m; j>=1; j--)
if(i==n&&j==m)
f[i][j]=a[i][j];
else
f[i][j]=max(f[i+1][j],f[i][j+1])+a[i][j];
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
if(i==1&&j==1)
ff[i][j]=a[i][j];
else
ff[i][j]=max(ff[i-1][j],ff[i][j-1])+a[i][j];
int t;
cin>>t;
while(t--)
solve();
}