本文共 2137 字,大约阅读时间需要 7 分钟。
链接:
同类题:
题意:给一个n*n矩阵(1<=n<=9)。从(1,1)到(n,n)走两次,第一次走过的方格处的值全变为0.求两条路径经过的所有值的和的最大值为多少。
思路:首先看见这一题,感觉并不是一眼能看懂的那种题。做惯了简单题,就不想思考了。为了改变这种坏习惯,我决定还是想一下这一题。最后想到的思路就是,第一次取路径最大值,然后再回溯回去,路径上的值全部赋0,再求一遍最大值。
写代码。。。过样例。。。提交。。。竟然还得了80分,只能说这个数据太水了,我都没打算能得多少分。
然后还是看了题解(真不知道应该什么时候看题解什么时候不看题解)。原来是思维数组(emmm,没涉及过)。看过思路之后,直接写代码,过了。方法还是挺简单的,但是没做过这种题,想不到。
四维DP模板题??dp[i][j][k][t]表示第一个人走(i,j)路径,第二个人走(k,t)路径,然后dp[i][j][k][t]=max(dp[i-1][j][k-1][t],dp[i-1][j][k][t-1],dp[i][j-1][k-1][t],dp[i][j-1][k][t-1])+mp[i][j]+mp[k][t];//注意i=k,j=t时减一个mp[i][j]。
最后贴代码:
#include#define ll long long#define ld long double#define pi acos(-1)#define pb push_back#define mst(a, i) memset(a, i, sizeof(a))#define pii pair #define pll pair #define fi first#define se second#define dbg(x) cout << #x << "===" << x << endl#define dbgg(i, x) cout << #x << "[" << i << "]===" << x[i] << endlusing namespace std;template void read(T &x){T res=0,f=1;char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)){res=(res<<3)+(res<<1)+c-'0';c=getchar();}x=res*f;}void print(ll x){if(x<0){putchar('-');x=-x;}if(x>9)print(x/10);putchar(x%10+'0');}const ll maxn = 1 + 10;const ll mod = 1e9 + 7;ll n,mp[maxn][maxn];ll x,y,k;ll dp[maxn][maxn][maxn][maxn];ll gcd(ll a,ll b){return (b==0)?a:gcd(b,a%b);}ll qpow(ll a,ll p,ll mod){ll ans=1;a=a%mod;while(p){if(p&1)ans=(ans*a)%mod;p>>=1;a=(a*a)%mod;}return ans;}ll ksm(ll a,ll b){ll ret=1; while(b){if(b&1)ret=ret*a%mod;a=a*a%mod;b>>=1;} return ret;}int main() { int T = 1; // read(T); while (T--) { read(n); while(scanf("%lld%lld%lld",&x,&y,&k)!=EOF){ if(x==0&&y==0&&k==0) break; mp[x][y]=k; } for(ll i=1;i<=n;i++){ for(ll j=1;j<=n;j++){ for(ll k=1;k<=n;k++){ for(ll t=1;t<=n;t++){ dp[i][j][k][t]=max(max(dp[i-1][j][k-1][t],dp[i-1][j][k][t-1]),max(dp[i][j-1][k-1][t],dp[i][j-1][k][t-1]))+mp[i][j]+mp[k][t]; if(i==k&&j==t) dp[i][j][k][t]-=mp[i][j]; } } } } cout< <
转载地址:http://ihst.baihongyu.com/