Codeforces Round #642 (Div. 3) E,F

E

题意:给定一个字符串,然后把给定的字符串变为合法序列,即每两个1之间的距离严格等于k
题解:构建dp数组
dp[i][0/1]当前第i位填0还是填1的最小操作数
图片说明
当前位置如果填0,所求值.即i-1位填0还是填1的最小加上这位是否为1
图片说明
当前位置如果填1,所求值即从i-k全部填0,所需要的数量再加上i-k位填1的操作数,或者从0到i全部填0,两者取最小,再加上该位是否为0

#include<bits/stdc++.h>
#define ll long long 
using namespace std;
int dp[maxn][2];
int sum[maxn];
char s[maxn];
int main() {
    int t; cin >> t;
    int cnt = 0;
    while (t--) {
        int n, k;
        cin >> n >> k;
        cin >> (s + 1);
        for (int i = 1; i <= n; i++) {
            if (s[i] == '1')
                sum[i] = sum[i - 1] + 1;
            else
                sum[i] = sum[i - 1];
        }

        for (int i = 1; i <= n; i++) {
            int las = max(0, i - k);
            //当前位是0
            dp[i][0] = min(dp[i - 1][1], dp[i - 1][0]) + (s[i] == '1');
            //当前位是1,可以考虑前面都为0,或者k个之前是1
            dp[i][1] = min(dp[las][1] + sum[i - 1] - sum[las], sum[i - 1]) + (s[i] == '0');
        }
        cout << min(dp[n][0], dp[n][1]) << endl;
    }
}

F

题意:给定一个n*m的矩阵,然后只能向下或向右移动,然后每次移动的位置必须满足两者相差1,即3->4为成立,3->5不成立,现在可以对于每一个数可以进行任意次的-1操作,变成负数也行,然后来求从(1,1)到(n,m)最小操作数
题解:选定一个基点,然后枚举来求,如果操作数最小,那么最好是保证一个数不变才能求得最小操作数
然后对于每一个基点,来求从(1,1)到(n,m)得最小操作数,具体看代码

#include<bits/stdc++.h>
#define dbg(x) cout<<#x<<" = "<<x<<endl;
#define INF 0x3f3f3f3f
#define eps 1e-6

using namespace std;
typedef long long LL;   
typedef pair<int, int> P;
const int maxn = 120;
const int mod = 1000000007;
const LL llinf = 1e18;
LL a[maxn][maxn], dp[maxn][maxn];

int main()
{
    int t, n, m, i, j, k;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%d %d", &n, &m);
        for(i=0;i<n;i++)
            for(j=0;j<m;j++)
                scanf("%I64d", &a[i][j]);
        LL ans = llinf;
        for(int a1=0;a1<n;a1++)
            for(int a2=0;a2<m;a2++)
        if(a[0][0] >= a[a1][a2]-a1-a2)
        {
            LL ps = a[a1][a2]-a1-a2;
            dp[0][0] = a[0][0]-ps;
            for(j=1;j<n;j++)
                if(a[j][0]<ps+j || dp[j-1][0] == llinf)dp[j][0] = llinf;
                else dp[j][0] = min(llinf, dp[j-1][0] + a[j][0]-ps-j);
            for(j=1;j<m;j++)
                if(a[0][j]<ps+j || dp[0][j-1] == llinf)dp[0][j] = llinf;
                else dp[0][j] = min(llinf, dp[0][j-1] + a[0][j]-ps-j);
            for(j=1;j<n;j++)
                for(k=1;k<m;k++)
                {
                    dp[j][k] = llinf;
                    if(a[j][k]<ps+j+k)continue;
                    dp[j][k] = min(dp[j][k], dp[j-1][k]+a[j][k]-ps-j-k);
                    dp[j][k] = min(dp[j][k], dp[j][k-1]+a[j][k]-ps-j-k);
                }
            ans = min(ans, dp[n-1][m-1]);
        }
        printf("%I64d\n", ans);
    }
    return 0;
}
全部评论

相关推荐

工作基本定了,比较满意。这深度学习真是难搞啊,论文看不懂,代码看不懂,不会改,创新点???&nbsp;还有一个月中期,怎么搞,已经抑郁了,没有小论文要求,我真是非常幸运了,不然就我这科研能力…………&nbsp;感觉自己对自己失去信心,无时无刻不在否定自己取得一些成绩都是运气好罢了,真的能顺利毕业吗?严重内耗、无力感爆棚啊…………
AI牛可乐:哎呀,听起来你最近压力好大呀,毕业论文和工作的双重压力一定让你感觉像是背了两座山呢。深度学习确实挺复杂的,就像是要在一片迷雾中找到出路一样。但是,你已经很棒了,工作都定好了,这是很大的成就呢! 论文的事情,别太担心。每个人都有看不懂代码和论文的时候,这是正常的。至于创新点嘛,有时候灵感就像小猫一样,需要一点一点地哄出来的。你可以先试试把你看过的资料整理一下,说不定就能找到新的思路呢。 中期答辩前,你可以列个计划,一步一步来,把大问题分解成小问题,一点一点克服。记得,你不是一个人在战斗,你的导师、同学都是你的战友哦。 至于信心嘛,别否定自己,每个人都会有低谷的时候。你已经取得的成绩,都是你实力的体现。毕业不是问题,只要你不放弃,就一定能顺利走过去的。加油哦,我相信你可以的! 对了,如果你愿意的话,可以点击我的头像,我们私信聊,也许我能帮你出出主意,或者就是简单地聊聊天,分散一下你的注意力也好呀。🐮💪🌟
点赞 评论 收藏
分享
牛舌:如果我不想去,不管对方给了多少,我一般都会说你们给得太低了。这样他们就会给下一个offer的人更高的薪资了。
点赞 评论 收藏
分享
10-09 00:50
已编辑
长江大学 算法工程师
不期而遇的夏天:1.同学你面试评价不错,概率很大,请耐心等待;2.你的排名比较靠前,不要担心,耐心等待;3.问题不大,正在审批,不要着急签其他公司,等等我们!4.预计9月中下旬,安心过节;5.下周会有结果,请耐心等待下;6.可能国庆节前后,一有结果我马上通知你;7.预计10月中旬,再坚持一下;8.正在走流程,就这两天了;9.同学,结果我也不知道,你如果查到了也告诉我一声;10.同学你出线不明朗,建议签其他公司保底!11.同学你找了哪些公司,我也在找工作。
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务