上午
照旧,听了20年12月的英语四级听力,嗯……不是很容易,这些题目。
写“P2392 kkksc03考前临时抱佛脚“,写出来了,在下午……
题目为:
得出的代码为:
#include <iostream>
#include <memory.h>
#include <algorithm>
using namespace std;
int main()
{
int s[4],dp[3000],n[4][100],sum=0,ans=0;
for(int i=0;i<4;i++)
cin >>s[i];
for(int i=0;i<4;i++)
{
for(int j=0;j<s[i];j++)
{
cin >>n[i][j];
sum+=n[i][j];//计算总时长
}
for(int k=0;k<s[i];k++)//每道题的所需时间都要使用一次,这就是要尽力达到最接近总时长的一半
for(int l=sum/2;l>=n[i][k];l--)//当然,如果某道题的所需时间超过了总时长的一半,它肯定是要和其他题目一起写才可达到
//写完题目的最少时间,所以不单独写超过总时长一半的题目,这是“l>=n[i][k]”的含义
//l--的意思是要算出最接近其他时长的做题时间,因为之后会用到其他时长
//的dp来实现01背包
dp[l]=max(dp[l],dp[l-n[i][k]]+n[i][k]);//使用01背包方法,算出最接近l的时长
ans+=sum-dp[sum/2];
sum=0;
memset(dp,0,sizeof(dp));//不可重复使用dp中的内容
}
cout << ans;
}
//此题思路为:需要达到的是左右脑的复习平衡。dp[l]代表最接近l的复习时间,而每次l会为总时间的一半,其实要求出的是最接近
//总时长一半的复习时间,当某一方脑的复习时间达到最接近总时间的一半时,另一方脑中的时长即为复习完此科目所需的时间
写这题还复习了一遍01背包问题,说起来容易,做起来真不容易啊……
好消息是更熟练地使用c++咯。
01背包的特征(我以为)是分为要和不要的两个情况,然后就是dp数组打表,其中dp数组的下标的含义必须要设置好,不然写得很乱。这个题目中就把dp中下标代表的是最接近此下标时间的复习题目时间,原本01背包是用来求背包中放物品而求得最大价值的,好像,差不多含义,所以可以用01背包来解嘛。之前用贪心写了半天,结果自己打出来的示例是对的,可交上去就全都是错的……然后看到题解上的人说贪心不能写……
下午
写”P2036 [COCI2008-2009#2] PERKET“,晚上才写出来……
题目是:
得出来的代码是:
#include <iostream>
#include <cmath>
#include <memory.h>
#include <algorithm>
using namespace std;
int n,s[15][2],ans=0x7fffffff;//将ans定为大小允许范围内的最大值
void dfs(int cnt,int sw,int ba)
{
if(cnt==n)//cnt==n了,代表能加的都加了,不加的也到尽头了,可以计算最小绝对差了
{
if(sw==1&&ba==0)//题目要求酸度和苦度不同时为1和0,当sw==1且ba==0则代表这条路用有此禁止的情况
return;
if(abs(sw-ba)<ans)
ans=abs(sw-ba);
return;
}
//两个情况,加或不加
dfs(cnt+1,sw*s[cnt][0],ba+s[cnt][1]);
dfs(cnt+1,sw,ba);
}
int main()
{
cin >>n;
for(int i=0;i<n;i++)
cin >>s[i][0]>>s[i][1];
if(n==1)
{cout <<abs(s[0][0]-s[0][1]);return 0;}
else dfs(0,1,0);
cout <<ans;
}
长记性长记性,这题写出来后一看就是简单的dfs应用,所以啊,要能够灵活根据题目更改dfs的细节条件,要能够适应题目,要更好的理解dfs和回溯的结构。
晚上
就和上面说一样,写了”P2036 [COCI2008-2009#2] PERKET“。
之后一直在写八皇后,既然我没有直接说,那就代表我没写出来……
还是发一发现在写出来的代码记录一下吧。
#include <iostream>
#include <cmath>
#include <memory.h>
#include <algorithm>
using namespace std;
int mark[20][20]={0},ans[20][20]={0},n,k;
int path[8][2]={{1,1},{1,-1},{-1,-1},{-1,1},{0,1},{0,-1},{1,0},{-1,0}},m,l;
void dfs(int c,int cnt)
{
if(cnt==n+1)
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(mark[i][j]==1)
ans[m][l++]=j;
for(int j=0;j<l;j++)
cout <<ans[m][j]<<" ";
cout <<endl;
m++;
l=0;
return;
}
for(int i=1;i<=n;i++)
{
if(mark[c][i]==0)
{
mark[c][i]=1;
for(int j=0;j<8;j++)
{
int x=c+path[j][0];
int y=i+path[j][1];
while(x>=1&&x<=n&&y>=1&&y<=n)
{
mark[x][y]=2;
x=x+path[j][0];
y=y+path[j][1];
}
}
}
else continue;
dfs(c+1,cnt+1);
memset(mark,0,sizeof(mark));
}
}
int main()
{
cin >>n;
dfs(1,1);
for(int i=0;i<3;i++)
{
for(int j=0;j<n;j++)
cout <<ans[i][j]<<" ";
cout <<endl;
}
}
还差一些,感觉是回溯没有处理好,明天一定写出来!!!
明日计划
写出八皇后,再另外写两道搜索题。
继续努力,加油。
要坚持。