前言
这次应该算是去年放假以后第一次写代码吧,感觉脑子还是有点秀逗的,这次的题目感觉确实都是水题,居然有一题还没写出来,好像第四题做的时候没看到剩下来的70%的数据,以为是对语言70%的数据,再次表示读题很重要!!!(想起去年的EC真是心痛)。
分析
- 第一题,暴力模拟,只需要把所有满足情况的
9
宫格表示出来就好了,然后暴力判断给出的图案和几个满足条件的
9 宫格一样。 - 第二题,暴力,使用一个数据结构(我用的是priority_queue)来模拟整个过程就好了,二分答案,搞定。
- 第三题,暴力每一层的情况,发现直接就转化成了一个完全背包问题,转移方程: dp[v]=min(dp[v],dp[v−b[i]]+a[i]) ,复杂度为 o(nmK) 。
- 第四题,(两个数组的)正序(乘积和)>乱序>逆序。这样如果确定了那些位置放对空,哪些位置放对舰,就只有一种排列了。这个时候就可以暴力 16 个位置放了什么。一共个就是 216 种可能,然后每一种情况进行判断就好了。复杂度是 o(nm∗2nm)
代码
只贴一下第四题的代码,感觉第四题被我写得很烂,写了两遍一样的代码。写完以后想想完全没有必要的,看来还是要多想想再写。
#include <bits/stdc++.h>
using namespace std;
typedef pair <int,int> PII;
#define FOR(i,x,y) for(int i = x;i < y;++ i)
#define IFOR(i,x,y) for(int i = x;i > y;-- i)
#define mp make_pair
#define fi first
#define se second
const int maxn = 1000;
int n,m,t,S;
int a[4][4],p[maxn],q[maxn],lep,leq;
bool cmp(int a,int b) {return a > b;}
bool cmp_PII(PII a,PII b) {return a.fi == b.fi ? a.se < b.se : a.fi > b.fi;}
void work(){
sort(p,p+lep,cmp); sort(q,q+leq,cmp);
int ans = -1;
int cnt = n*m; int maxp = 1<<cnt;
FOR(i,0,maxp){
PII b[16],c[16];
int leb = 0,lec = 0;
FOR(j,0,cnt){
int x = j/m ,y = j%m;
if(i & (1<<j)) b[leb++] = mp(a[x][y],j);
else c[lec++] = mp(a[x][y],j);
}
sort(b,b+leb,cmp_PII); sort(c,c+lec,cmp_PII);
int lebp = min(leb,lep),sump = 0;
FOR(j,0,lebp) sump += b[j].fi*p[j];
if(sump < S) continue;
int lecq = min(lec,leq),sumq = 0;
FOR(j,0,lecq) sumq += c[j].fi*q[j];
ans = max(ans,sumq);
}
if(ans == -1) {printf("Not Exist\n");return;}
if(ans == 0) {printf("0\nNo\n");return;}
printf("%d\n",ans);
bool flag = false;
FOR(i,0,maxp){
PII b[16],c[16];
int leb = 0,lec = 0;
FOR(j,0,cnt){
int x = j/m ,y = j%m;
if(i & (1<<j)) b[leb++] = mp(a[x][y],j);
else c[lec++] = mp(a[x][y],j);
}
sort(b,b+leb,cmp_PII); sort(c,c+lec,cmp_PII);
int lebp = min(leb,lep),sump = 0;
FOR(j,0,lebp) sump += b[j].fi*p[j];
if(sump < S) continue;
int lecq = min(lec,leq),sumq = 0;
FOR(j,0,lecq) sumq += c[j].fi*q[j];
if(ans == sumq){
bool vis[4]; FOR(j,0,n) vis[j] = false;
FOR(j,0,lecq) vis[c[j].se/m] = true;
bool f = true;
FOR(j,0,n) if(!vis[j]) {f = false;break;}
if(f) {flag = true;break;}
}
}
if(flag) printf("Yes\n");
else printf("No\n");
return;
}
int main(){
int Q; scanf("%d",&Q);
while(Q--){
scanf("%d%d%d%d",&n,&m,&t,&S);
FOR(i,0,n) FOR(j,0,m) scanf("%d",&a[i][j]);
int u; lep = leq = 0;
FOR(i,0,t) scanf("%d",&u),p[lep++] = u;
FOR(i,0,t) scanf("%d",&u),q[leq++] = u;
work();
}
}