【DP】 HDU 5092 Seam Carving
从上到下找到一条路 要路上的值最小
如果有多条路径输出最靠右边的
#include <cstdio> #include <cstring> #include <cstdlib> #include <string> #include <iostream> #include <algorithm> #include <sstream> #include <cmath> using namespace std; #include <queue> #include <stack> #include <vector> #include <deque> #define cler(arr, val) memset(arr, val, sizeof(arr)) typedef long long LL; const int MAXN = 100200; const int MAXM = 6000010; const int INF = 0x3f3f3f3f; const int mod = 1000000007; LL a[133][133],dp[133][133],pre[133][133]; vector<int>point; int main() { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); #endif int t,n,m,cas=1; cin>>t; while(t--) { cin>>n>>m; cler(a,0);cler(pre,0); cler(dp,0); for(int i=0;i<=n;i++) for(int j=0;j<=m+2;j++) dp[i][j]=(LL)INF; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%I64d",&a[i][j]); for(int i=n;i>=1;i--) { for(int j=1;j<=m;j++) { for(int k=-1;k<=1;k++) { if(dp[i][j]>=dp[i+1][j+k]+a[i][j]) { pre[i][j]=j+k; dp[i][j]=dp[i+1][j+k]+a[i][j]; } } } } printf("Case %d\n",cas++); LL ans=INF; point.clear(); for(int i=1;i<=m;i++) { if(ans>dp[1][i]) { point.clear(); ans=dp[1][i]; point.push_back(i); } else if(ans==dp[1][i]) point.push_back(i); } LL num,sum=0; for(int j=0;j<point.size();j++) { LL p=point[j]; LL cc=0; for(int i=1;i<=n;i++) { cc+=p; p=pre[i][p]; } if(cc>sum) sum=cc,num=j; } LL p=point[num]; for(int i=1;i<=n;i++) { printf("%I64d%c",p,i==n?'\n':' '); p=pre[i][p]; } //cout<<ans<<endl; } return 0; }