P1070 [NOIP2009 普及组] 道路游戏
dfs-> dp[i]=max(dp[i],dp[i-k]+∑-cost[ last ])
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<bits/stdc++.h> #define ll long long #define ddd printf("-----------------debug\n"); using namespace std; int n,m,p,dp[1005],a[1005][1005],cost[1005]; int main() { ios::sync_with_stdio(false); memset(dp,-0x3f3f3f3f,sizeof(dp)); cin>>n>>m>>p; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) cin>>a[i][j]; } for(int i=1;i<=n;i++) cin>>cost[i]; dp[0]=0;//side val for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++) { int sum=0; for(int k=1;k<=i&&k<=p;k++) { int last; if(j-k<=0) last=n+(j-k)%n; else last=j-k; sum+=a[last][1+i-k]; dp[i]=max(dp[i],dp[i-k]-cost[last]+sum); } } } cout<<dp[m]; return 0; } /* #include <iostream> #include <cstring> using namespace std; int a[1005][1005],cost[1005]; int dp[1005]; int main() { int n,m,p; cin>>n>>m>>p; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>a[i][j]; for(int i=1;i<=n;i++) cin>>cost[i]; memset(dp,~0x7f,sizeof(dp)); //注意初始化,一定要附一个极小的值,因为计算过程中可能会出现负数! for(int i=1;i<=m;i++) //枚举时间,前i分钟 { for(int j=1;j<=n;j++) //枚举结束位置,以j号工厂结束 { int sum=0; for(int k=1;k<=p && k<=i;k++) { int last; //last表示走k步前,工厂是多少号 if(j-k<=0) last=n+(j-k)%n; else last=j-k; //环形道路 sum+=a[last][i-k+1]; //求和 dp[i]=max(dp[i],dp[i-k]+sum-cost[last]); //状态转移方程,第i分钟的最大值=max(前i-k分钟最大值+走过来得到金币数) } } } cout<<dp[m]; //第m分钟的最大值,及答案 return 0; } */

浙公网安备 33010602011771号