学习记录7

上午

照旧,听了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;
    }

}

还差一些,感觉是回溯没有处理好,明天一定写出来!!!

明日计划

写出八皇后,再另外写两道搜索题。

继续努力,加油。

要坚持。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值