http://acm.hi-54.com/problem.php?pid=2113
題意:
給出總金錢數E,和每次搬運需要的金錢數F,(每次可以拿走體積為1 的小正方體,當然也可以將一個小正方體從i出移到j處 花費都是F)
然后給出矩陣行和列n,m (e<10^12,n<100,m<100)
下面就是n*m個數,不同的數表示對應的高度。
求出在三視圖保持不變以及不超過總錢數的前提下,所能拿出的小正方體的最大體積。(最完美翻譯 ,請網上查找英文版本)
題解思路:根據矩陣,求出最優的三視圖矩陣,然后比較得出最優解。
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<queue> #include<cmath> using namespace std; #define INF 0x3f3f3f3f #define LL long long #define N 103 LL e,f,n,m; LL a[N][N],map[N][N],x[N],y[N],xx[N],yy[N]; void qingkong() { memset(map,0,sizeof(map)); memset(a,0,sizeof(a)); memset(xx,0,sizeof(xx)); memset(yy,0,sizeof(yy)); } void zuidazhi() { for(int i=1; i<=n; i++) { LL maxx=-1; for(int j=1; j<=m; j++) maxx=max(maxx,map[i][j]); x[i]=maxx;///各行的最大值 } for(int i=1; i<=m; i++) { LL maxx=-1; for(int j=1; j<=n; j++) maxx=max(map[j][i],maxx); y[i]=maxx;///各列的最大值 } } void gouzaozuiyou() {///先將矩陣按照三視圖構造成最優圖 for(int i=1; i<=n; i++) for(int j=1; j<=m; j++) if(x[i]==y[j]&&!yy[j]&&map[i][j]) {///行列相同為最優值 xx[i]=1; yy[j]=1;///表示行列最大值是否使用 a[i][j]=x[i]; break; } for(int i=1; i<=n; i++) {//將各行剩余的最大值 插入合適的列中 if(xx[i]) continue; for(int j=1; j<=m; j++) {///即列最大值大于等于行最大值時 if(y[j]>=x[i]&&map[i][j]) {///不要忘記等于的情況 a[i][j]=x[i]; xx[i]=1; break; } } } for(int i=1; i<=m; i++) {///同上 if(yy[i]) continue; for(int j=1; j<=n; j++) { if(x[j]>=y[i]&&map[j][i]) { a[j][i]=y[i]; yy[i]=1; break; } } } for(int i=1; i<=n; i++) { for(int j=1; j<=m; j++) { int c=0,d=0; for(int k=1; k<=n; k++) if(a[i][j]==a[k][j]&&i!=k) c=1; for(int k=1; k<=m; k++) if(a[i][j]==a[i][k]&&j!=k) d=1; if(c&&d&&a[i][j]) a[i][j]=1; } } } void gouchengtu()///最終的最優構成圖 { for(int i=1; i<=n; i++) { for(int j=1; j<=m; j++) printf("%lld ",a[i][j]); printf("\n"); } } void shujucha()///數據差 { ///根據題意 找出 數據查 求出最佳值 LL ans=0,sum=0; for(int i=1; i<=n; i++) { for(int j=1; j<=m; j++) { if(map[i][j]>a[i][j]) sum+=map[i][j]; ans+=map[i][j]-a[i][j]; } } if(sum>=e/f) printf("%lld\n",e/f); else printf("%lld\n",ans); } int main() { int T; scanf("%d",&T); while(T--) { qingkong(); scanf("%lld %lld %lld %lld",&e,&f,&n,&m); for(int i=1; i<=n; i++) for(int j=1; j<=m; j++) scanf("%lld",&map[i][j]); for(int i=1; i<=n; i++) for(int j=1; j<=m; j++) if(!a[i][j]&&map[i][j]) a[i][j]=1; zuidazhi();///求出各行各列的最大值 gouzaozuiyou();///按照三視圖 求出最優 /// gouchengtu(); /// 給出矩陣的面積最小圖 shujucha();///根據題意 求出相應結果 } return 0; }
浙公網安備 33010602011771號