1. 程式人生 > >Codeforces Round #461 (Div. 2) 題解

Codeforces Round #461 (Div. 2) 題解

產生 mat 是否 amp %d str print sin 輸出

Codeforces Round #461 (Div. 2)

Codeforces 922C

題意

給定\(n,k \le 10^{18}\),判斷是否對於所有的$ i \le k,n mod i$都是不同的

解題思路

首先\(n\ mod\ 1=0\),為了不相同\(n\ mod\ 2=1\)\(n\ mod\ 3=2\)……

\(n\ mod\ i=i-1\)\(n+1\ mod\ i=0\)

直接暴力判斷對所有的\(i\)是否成立即可,由於階乘的增長速度很快,檢查的次數幾乎是常數

AC代碼

#include <bits/stdc++.h>
using namespace std;
long
long n,k; bool solve() { for (long long i=1;i<=k;i++) if((n+1)%i) return false; return true; } int main(int argc, char const *argv[]) { scanf("%I64d%I64d",&n,&k); if(solve()) puts("Yes"); else puts("No"); return 0; }

Codeforces 922D

題意

給定若幹由\(s\)\(h\)組成的字符串,輸出將這些字符串拼接後這樣的對的數量的最大值\(i<j,s_i=‘s‘,s_j=‘h‘\)

解題思路

對於兩個字符串\(A,B\),相應\(s,h\)的數量分別為\(s_{str},h_{str}\) ,設不算這兩個串互相產生的對對答案的貢獻的其他貢獻為\(W\),則當前對的數量為\(W+s_Ah_B\),交換後為\(W+s_Bh_A\)

因此按照\(s_{str}/h_{str}\)排序後即是最佳拼接方案,隨後計算對的數量即可

AC代碼

#include <bits/stdc++.h>
using namespace std;
const
int maxn=100007; struct node { string str; long long s,h; }noise[maxn]; int order[maxn]; bool cmp(int l,int r) { return noise[l].s*noise[r].h>noise[l].h*noise[r].s; } int main(int argc, char const *argv[]) { int n; scanf("%d",&n); for (int i=0;i<n;i++) order[i]=i; for (int i=0;i<n;i++) { cin>>noise[i].str; long long s=0,h=0; for (int j=0;j<noise[i].str.size();j++) { if(noise[i].str[j]==‘s‘) s++; else if(noise[i].str[j]==‘h‘) h++; } noise[i].s=s; noise[i].h=h; } sort(order,order+n,cmp); long long ans=0,bs=0; for (int i=0;i<n;i++) for (int j=0;j<noise[order[i]].str.size();j++) { if(noise[order[i]].str[j]==‘h‘) ans+=bs; else if(noise[order[i]].str[j]==‘s‘) bs++; } printf("%I64d\n",ans); return 0; }

Codeforces 922E

題意

我覺得是本題難點之一,不想寫了

思路

即狀態dp[i][k]為經過了\(i\)個樹召喚了\(k\)個鳥剩余mana的最大值,狀態轉移方程為:

\[dp[i][j]=max(dp[i][j],min(dp[i-1][j-k]+X,W+(j-k)\times B)-cost_i\times k)\]

AC代碼

#include <bits/stdc++.h>
using namespace std;
const int maxn=1007;
long long n,w,b,x;
long long c[maxn],cost[maxn];
long long dp[maxn][10*maxn];
int main(int argc, char const *argv[])
{
    scanf("%I64d%I64d%I64d%I64d",&n,&w,&b,&x);
    for (int i=1;i<=n;i++)  scanf("%I64d",&c[i]);
    for (int i=1;i<=n;i++)  scanf("%I64d",&cost[i]);
    memset(dp,-1,sizeof(dp));
    dp[0][0]=w;
    for (int i=0;i<=n-1;i++)
    {
        int j=0;
        while(dp[i][j]!=-1)
        {
            if(i>0)
                dp[i+1][j]=min(max(dp[i+1][j],dp[i][j]+x),w+j*b);
            else
                dp[i+1][j]=min(max(dp[i+1][j],dp[i][j]),w+j*b);
            for (int k=1;k<=c[i+1];k++)
            {
                long long nxt=min(dp[i][j]+(i>0?x:0),w+j*b)-cost[i+1]*k;
                if(nxt>=0)  dp[i+1][j+k]=max(dp[i+1][j+k],nxt);
            }
            j++;
        }
    }
    for (int i=1;i<=10001;i++)
        if(dp[n][i]<0)
        {
            printf("%d\n",i-1);
            return 0;
        }
    return 0;
}

Codeforces Round #461 (Div. 2) 題解