寻宝游戏 HDU - 6289 (DP)
小Q最近迷上了一款尋寶游戲,這款游戲中每局都會生成一個n×mn×m的網格地圖,從上往下依次編號為第11行到第nn行,從左往右依次編號為第11列到第mm列。每個格子上都有不同數量的金幣,第ii行第jj列的格子上的金幣數量為ai,jai,j。?
小Q一開始位于(1,1)(1,1),每次他可以往右或者往下走,每當他經過某個格子時,他就可以拿走這個格子上的所有金幣。小Q不能走出這個地圖,當小Q不能再行動時,游戲結束。顯然當且僅當小Q位于(n,m)(n,m)時,游戲才會結束。?
一輪游戲的得分為這一輪中收集到的金幣總量,而在游戲開始前,因為小Q是超級VIP用戶,所以他有kk次機會交換某兩個格子中的金幣數。這kk次機會不一定要用完,請寫一個程序幫助小Q在一輪內拿到盡可能多的金幣。
Input
第一行包含一個正整數T(1≤T≤10)T(1≤T≤10),表示測試數據的組數。?
每組數據第一行包含三個整數n,m,k(2≤n,m≤50,0≤k≤20)n,m,k(2≤n,m≤50,0≤k≤20),分別表示地圖的長寬以及交換的次數。?
接下來nn行,每行mm個整數ai,j(0≤ai,j≤106)ai,j(0≤ai,j≤106),依次表示每個格子中金幣的數量。
Output
對于每組數據,輸出一行一個整數,即能收集到的金幣數量的最大可能值。
Sample Input
2 3 4 0 1 2 3 4 9 8 7 6 5 4 7 2 5 5 1 9 9 9 0 0 0 0 9 0 0 0 0 0 0 0 0 0 9 0 0 9 0 9 9 9Sample Output
34 81 #include<iostream> using namespace std; inline bool cmp(int x,int y){return x>y; } const int max1=55; const int max2=25; const int inf=0x3f3f3f3f; int n,m,k; int dp[max1][max1][max2][max2]; int a[max1][max1]; int tot; int b[max1]; int main(){int t;cin>>t;while(t--){memset(dp,-0x3f,sizeof(dp));cin>>n>>m>>k;for(int i=0;i<n;i++) for(int j=0;j<m;j++) cin>>a[i][j];dp[0][0][0][0]=a[0][0];dp[0][0][0][1]=0;for(int i=0;i<n;i++){for(int j=0;j<m;j++){if(i==0&j==0) continue;tot=0;if(i) for(int y=j+1;y<m;y++) b[tot++]=a[i-1][y];for(int x=0;x<j;x++) b[tot++]=a[i][x];sort(b,b+tot,cmp);for(int used=0;used<=k;used++){for(int bal=0;bal<i+j+1&&bal<=k;bal++){int ans=-inf;if(i){ans=max(ans,dp[i-1][j][used][bal]+a[i][j]);if(bal) ans=max(ans,dp[i-1][j][used][bal-1]);int sum=0;int it=0;for(int cntuse=1;cntuse<=k&&cntuse<=tot;cntuse++){sum+=b[it++];ans=max(ans,dp[i-1][j][used-cntuse][bal]+sum+a[i][j]);if(bal) ans=max(ans,dp[i-1][j][used-cntuse][bal-1]+sum);}}if(j){ans=max(ans,dp[i][j-1][used][bal]+a[i][j]);if(bal) ans=max(ans,dp[i][j-1][used][bal-1]);}dp[i][j][used][bal]=ans;}}}}int ans=0;for(int i=0;i<=k;i++){ans=max(ans,dp[n-1][m-1][i][i]);}cout<<ans<<endl;}return 0; }總結
以上是生活随笔為你收集整理的寻宝游戏 HDU - 6289 (DP)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux git ssh目录权限,Gi
- 下一篇: 在linux下使用360随身wifi 2