多维DP
一眼看出来就是DP
状态转移: f[i][j] = max(f[i-1][j],f[i-1][j-1],f[i-1][j+1])+v[i][j];
#include<bits/stdc++.h> using namespace std; #define LOACL freopen("in","r",stdin);\ freopen("out","w",stdout); const int inf = 987654321; const int sz = 1e6 + 5; const int mod = 1e9 + 7; const int sqrtn = 300; #define add(u,v,w) (e[++tot]=(edge){v,head[u],1},head[u]=tot;) #define f(i,l,r) for(int i=(int)l;i<=(int)r;++i) #define g(i,l,r) for(int i=(int)l;i>=(int)r;--i) #define CLR(arr,val) memset(arr,val,sizeof(arr)) typedef long long ll; int n,m,a[300][300],f[300][300],k; int main() { LOACL cin>>n>>m; k=m/2+1; f(i,1,n)f(j,1,m)cin>>a[i][j]; f(i,1,n)f(j,1,m) { f[i][j]=max(max(f[i-1][j],f[i-1][j-1]),f[i-1][j+1])+a[i][j]; } cout<<max(max(f[n][k],f[n][k-1]),f[n][k+1])<<endl; return 0; }
P1006 传纸条
金字塔升级版
f[i][j][k] 第几步 x1坐标x2坐标 的好感度
f[i][j][k] = max(f[i-1][j-1][k-1],f[i-1][j][k-1],f[i-1][j-1][k],f[i-1][j][k])+a[j][i-j+1]+a[k][i-k+1];
#include<bits/stdc++.h> using namespace std; #define LOACL freopen("in","r",stdin);\ freopen("out","w",stdout); const int inf = 987654321; const int sz = 1e6 + 5; const int mod = 1e9 + 7; const int sqrtn = 300; #define add(u,v,w) (e[++tot]=(edge){v,head[u],1},head[u]=tot;) #define f(i,l,r) for(int i=(int)l;i<=(int)r;++i) #define g(i,l,r) for(int i=(int)l;i>=(int)r;--i) #define CLR(arr,val) memset(arr,val,sizeof(arr)) typedef long long ll; int n,m; int a[300][300],f[600][300][300]; int mm( int a,int b,int c,int d) { return max(a,max(b,max(c,d))); } int main() { LOACL cin>>n>>m; f(i,1,n)f(j,1,m)cin>>a[i][j]; f(k,1,n+m-1) f(i,1,n)f(j,1,n) { if(k-i+1<1||k-j+1<1) continue; // f[k][i][j]=mm(f[k-1][i][j],f[k-1][i-1][j-1],f[k-1][i][j-1],f[k-1][i-1][j]) + a[i][k-i+1] + a[j][k-j+1]; f[k][i][j]=mm(f[k-1][i][j],f[k-1][i-1][j-1],f[k-1][i-1][j],f[k-1][i][j-1])+a[i][k-i+1]+a[j][k-j+1]; if(i==j)f[k][i][j]-=a[i][k-i+1]; } cout<<f[n+m-1][n][n]<<endl; return 0; }
P1387 最大正方形
f[i][j] 运行到i行j 列 判断左方、上方、左上方的最小值,再+1
f[i][j]=min( f[i-1][j-1],f[i-1][j],f[i][j-1])+1;
#include<bits/stdc++.h> using namespace std; #define LOACL freopen("in","r",stdin);\ freopen("out","w",stdout); const int inf = 987654321; const int sz = 1e6 + 5; const int mod = 1e9 + 7; const int sqrtn = 300; #define add(u,v,w) (e[++tot]=(edge){v,head[u],1},head[u]=tot;) #define f(i,l,r) for(int i=(int)l;i<=(int)r;++i) #define g(i,l,r) for(int i=(int)l;i>=(int)r;--i) #define CLR(arr,val) memset(arr,val,sizeof(arr)) typedef long long ll; int n,m; int a[300][300],f[300][300]; int main() { LOACL cin>>n>>m; f(i,1,n)f(j,1,m)cin>>a[i][j]; f(i,1,n)f(j,1,m) { if(a[i][j]==0) continue; f[i][j]=min(min(f[i-1][j-1],f[i-1][j]),f[i][j-1])+1; } int ans = 0; f(i,1,n)f(j,1,m) ans=max(ans,f[i][j]); cout<<ans<<endl; return 0; }
P1417 烹调方案
划重点
a[x]-(p+c[x])*b[x]+a[y]-(p+c[x]+c[y])*by
a[y]-(p+c[y])*b[y]+a[x]-(p+c[y]+c[x])*bx
对这两个式子化简,得到①>②的条件是c[x]*b[y]<c[y]*b[x].
发现只要满足这个条件的物品对(x,y),x在y前的代价永远更优。
#include<bits/stdc++.h> using namespace std; #define LOACL freopen("in","r",stdin);\ freopen("out","w",stdout); const int inf = 987654321; const int sz = 1e6 + 5; const int mod = 1e9 + 7; const int sqrtn = 300; #define add(u,v,w) (e[++tot]=(edge){v,head[u],1},head[u]=tot;) #define f(i,l,r) for(ll i=(ll)l;i<=(ll)r;++i) #define g(i,l,r) for(ll i=(ll)l;i>=(ll)r;--i) #define CLR(arr,val) memset(arr,val,sizeof(arr)) typedef long long ll; ll t,n; struct node { ll a,b,c; }e[sz]; ll f[sz]; bool cmp(node a,node b) { return a.b*b.c >a.c*b.b; } int main() { LOACL cin>>t>>n; f(i,1,n)cin>>e[i].a; f(i,1,n)cin>>e[i].b; f(i,1,n)cin>>e[i].c; sort(e+1,e+n+1,cmp); f(i,1,n) g(j,t,e[i].c) // for(ll j = t; j - e[i].c >= 0; j--) f[j] = max(f[j], f[j-e[i].c] + e[i].a - j * e[i].b); ll maxx =0; f(i,1,t) maxx=max(maxx,f[i]); cout<<maxx<<endl; return 0; }
不摸着石头过河,难道要在温柔乡睡到天昏地暗。