你必须非常努力,才能看起来毫不费力。
莫名其妙搞出来了。。。
思路:
1:先找到每一行每一列最大的,进行标记。然后将不是每一行每一列最大的进行相加sum,并且赋值为1,说明sum就是可以最直接获得的。
2:有一些情况可以移动。(***不是每一行每一列的最大值都被赋值成了1)
1 20//不可以移动最大的
20 1
30 20//可以将20移动到1,这样可以最大限度的拿取
20 1
3:然后第二种可以这样移动的可以有很多个,我用f1[]记录移动去骗取照相机的移动数,即是将20中的19个一到1上,变成
30 20
1 20
那第一行第二列的就又有t=19个可以拿了,
用f2[]记录,f2[]=f1[]+t
4:然后转换成一个动态规划,我将这个动态规划问题转换成了一个小问题:
有30元去买糖,糖一块钱一个
有n件包裹,每打开一个包裹也需要掏钱,求最多可以得到多少糖
第一个数,第二个数,表示的是打开包裹的花费、以及包裹里有多少糖
3 4
表示的是这个包裹打开需要3块钱打开费,里面有4个糖。
问题链接:
http://222.22.65.164/problem.php?id=4203
问题4203--Image Recognition
4203: Image Recognition
时间限制: 6 Sec 内存限制: 128 MB
提交: 1 解决: 1
[提交] [状态] [讨论版] [命题人:外部导入]
题目描述
The monitoring system without any person does not necessarily require a large number of dynamic images. It is enough to transport an immobile image in ** seconds in most practical condition.
In the JD-T warehouse, the goods is stored in large cubical crates, all of which have the same dimensions. The crates are stacked in neat piles, forming a three-dimensional grid. The remote online monitoring system takes pictures of the piles once in S seconds using three cameras: a front camera, a side camera and a top camera. The image from the front camera shows the height of the tallest pile in each column, the image from the side camera shows the height of the tallest pile in each row, and the image from the top camera shows whether or not each pile is empty. If the monitoring system detects a change in any of the images, it sounds an alarm.
Figure I-1 shows a possible layout of the grid and the image from each of the cameras.
Figure I-2 , I-3 and figure I-1 have the same images from each of the cameras.
A theft gang noticed this unmanned warehouse. They found that it took T seconds to transport a crate. They wants to steal as many crates as possible. Since they cannot disable the monitoring system, they plans to fool it by arranging the remaining crates into piles so that the next set of camera images are the same.
Is the remote online monitoring system safe? If it's not safe, the maximum number of crates that can be stolen while leaving a configuration of crates that will fool the monitoring system, camera images remain unchanged.
输入
The first line of the input contains one integer T, which is the number of test cases (1<=T<=6). Each test case specifies:
* Line 1: S T (1<=S=1012 1<=T=103 )
* Line 2: m n rows and columns in the grid, respectively. (1<=m, n<=100)
*Line 3..m+3: each line contains n integers, the heights (in crates) of the piles in the corresponding row. ( all heights are between 0 and 109 inclusive.)
输出
For each test case , print the maximum number of crates that can be stolen without being detected.
样例输入
3
10000 100
5 5
1 4 0 5 2
2 1 2 0 1
0 2 3 4 4
0 3 0 3 1
1 2 2 1 1
10000 100
2 3
50 20 3
20 10 3
1000 99
2 3
50 20 3
20 10 3
样例输出
9
30
10
来源/分类
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f
const int maxn=100+10;
int Map[maxn][maxn];
int col[maxn],row[maxn];
int flag[maxn][maxn];
int main()
{
int T,i,j,k,p,n,m;
ll s,t;
cin >> T;
while(T--)
{
memset(flag,-1,sizeof(flag));
scanf("%lld %lld %d%d",&s,&t,&n,&m);
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
scanf("%d",&Map[i][j]);
}
}
if(t>=s){
printf("0");
continue;
}
int Max=0;
for(i=1;i<=n;i++){//找出每一行的最大值
int Max=0;
for(j=1;j<=m;j++){
if(Max<Map[i][j]){
row[i]=j;
Max=Map[i][j];
}
}
}
for(i=1;i<=n;i++)
flag[i][row[i]]=Map[i][row[i]];
for(i=1;i<=m;i++){//找出每一列的最大值
int Max=0;
for(j=1;j<=n;j++){
if(Max<Map[j][i]){
col[i]=j;
Max=Map[j][i];
}
}
}
for(i=1;i<=m;i++)
flag[col[i]][i]=Map[col[i]][i];
ll cnt=0;
if(0==s%t) cnt=s/t-1;
else cnt=s/t;
ll sum=0;
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){//先尽量拿可以拿的
if(-1==flag[i][j]&&0!=Map[i][j]){
sum+=Map[i][j]-1;
Map[i][j]=1;
}
}
}
if(sum>=cnt){
printf("%lld\n",cnt);
continue;
}
cnt-=sum;
int f1[maxn]={0},f2[maxn]={0};//重量 价值 会改变 的背包问题
int k=0;
for(i=1;i<=n;i++){
//如果是所在行所在列都是最大的就不行
if(i==col[row[i]]) continue;
for(j=1;j<=m;j++){
if(-1==flag[col[j]][j]) continue;
if(Map[i][row[i]]==Map[col[j]][j] && !(Map[i][row[i]]>Map[i][j]&&Map[i][row[i]]>Map[col[j]][row[i]])){
if(Map[i][j]&&Map[i][row[i]]>Map[i][j]){//行列相交处有值
if(Map[i][row[i]]-Map[i][j]<=cnt){
flag[col[j]][j]=-1;
flag[i][row[i]]=-1;
flag[i][j]=1;
f1[k]=Map[i][row[i]]-Map[i][j];
f2[k]=Map[i][row[i]]-1+f1[k];
k++;
Map[i][row[i]]=Map[col[j]][j]=1;
Map[i][j]=Map[i][row[i]];
}
}
if(Map[col[j]][row[i]]&&Map[i][row[i]]>Map[col[j]][row[i]]){//行列相交处有值
if(Map[i][row[i]]-Map[col[j]][row[i]]<=cnt){
flag[col[j]][j]=-1;
flag[i][row[i]]=-1;
flag[col[j]][row[i]]=1;
f1[k]=Map[i][row[i]]-Map[col[j]][row[i]];
f2[k]=Map[i][row[i]]-1+f1[k];
k++;
Map[i][row[i]]=Map[col[j]][j]=1;
Map[col[j]][row[i]]=Map[i][row[i]];
}
}
}
if(-1==flag[col[j]][j]) break;
}
}
int dp[maxn];
memset(dp,-1,sizeof(dp));
dp[0]=0;
// int isopen[manx]={0};
for(i=0;i<k;i++){
for(j=22;j>=0;j--){
if(-1!=dp[j] && j+f1[i]<cnt){
for(k=j+f1[i]+1,p=1;k<=j+f2[i]&&k<=cnt;k++,p++){
dp[k]=max(dp[k],p);
}
}
}
}
Max=0;
for(i=0;i<=cnt;i++){
if(dp[i]>Max)
Max=dp[i];
}
printf("%lld\n",Max+sum);
}
return 0;
}