Seam Carving
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1432 Accepted Submission(s): 555
For an original image G of m*n, where m and n are the row and column of the image respectively. Fish obtained the corresponding energy matrix A. He knew every time a seam with the lowest energy should be carved. That is, the line with the lowest sum of energy passing through the pixels along the line, which is a 8-connected path vertically or horizontally.
Here your task is to carve a pixel from the first row to the final row along the seam. We call such seam a vertical seam.
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define mod 0x3f3f3f3f
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
int vis[101][101],a[101][101],dp[101][101];
int main()
{
int T;
scanf("%d", &T);
for(int t=1; t<=T; t++)
{
int n,m;
scanf("%d %d", &n, &m);
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++) scanf("%d", &a[i][j]);
}
for(int j=1; j<=m; j++) dp[n][j] = a[n][j];
for(int i=n-1; i>=1; i--)
{
for(int j=1; j<=m; j++)
{
dp[i][j]=dp[i+1][j];
vis[i][j]=j;
if(dp[i][j]>dp[i+1][j-1]&&j-1>=1&&i+1<=n)
{
dp[i][j]=dp[i+1][j-1];
vis[i][j]=j-1;
}
if(dp[i][j]>=dp[i+1][j+1]&&j+1<=m&&i+1<=n)
{
dp[i][j]=dp[i+1][j+1];
vis[i][j]=j+1;
}
dp[i][j]+=a[i][j];
}
}
int ans = mod;
int k;
for(int i=1; i<=m; i++)
{
if(dp[1][i]<=ans)
{
ans = dp[1][i];
k= i;
}
}
printf("Case %d\n%d", t, k);
for(int i=1; i<n; i++)
{
k = vis[i][k];
printf(" %d", k);
}
printf("\n");
}
return 0;
}
从下往上遍历:
#include<iostream> #include<cstdio> #include<cstdlib> #include<string> #include<cstring> #include<list> #include<queue> #include<stack> #include<map> #include<set> #include<algorithm> #include<cmath> #include<bitset> #include<climits> #define MAXN 1000 using namespace std; int back[MAXN][MAXN],dp[MAXN][MAXN],data[MAXN][MAXN]; int ans[MAXN],M,N; int main() { int T,times=1; cin>>T; while (T--) { memset(dp,0,sizeof(dp)); memset(back,0,sizeof(back)); cin>>M>>N; for (int i=1;i<=M;i++) for (int j=1;j<=N;j++){ scanf("%d",&data[i][j]); dp[i][j]=1000000; } for (int i=1;i<=N;i++) dp[1][i]=data[1][i]; for (int i=2;i<=M;i++) for (int j=1;j<=N;j++) { if (j+1<=N&&dp[i][j]>dp[i-1][j+1]+data[i][j]) dp[i][j]=dp[i-1][j+1]+data[i][j],back[i][j]=j+1; if (dp[i][j]>dp[i-1][j]+data[i][j]) dp[i][j]=dp[i-1][j]+data[i][j],back[i][j]=j; if (j-1>=1&&dp[i][j]>dp[i-1][j-1]+data[i][j]) dp[i][j]=dp[i-1][j-1]+data[i][j],back[i][j]=j-1; } int min=1000000,min_i=0; for (int i=N;i>=1;i--){ if(min>dp[M][i]) min=dp[M][i],min_i=i; } printf("Case %d\n",times++); for (int i=M;i>=1;i--) { ans[i]=min_i; min_i=back[i][min_i]; } for (int i=1;i<=M;i++) { printf("%d",ans[i]); if(M==i) printf("\n"); else printf(" "); } } return 0; }