---
# System prepended metadata

title: APCS 2020/10 題解

---

# APCS 2020/10 題解
## ==人力分配==
### <font color="0E81A6">題目</font>
[人力分配](https://zerojudge.tw/ShowProblem?problemid=f312)
### <font color="0E81A6">核心</font>
迴圈、條件判斷
### <font color="0E81A6">思路</font>
```c++=
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n,A1,A2,B1,B2,C1,C2;
    scanf("%d%d%d%d%d%d%d",&A1,&B1,&C1,&A2,&B2,&C2,&n);
    int maxProfit=INT_MIN,profit;
    for(int i=0;i<=n;i++)
    {
        int Y1=A1*i*i+B1*i+C1,Y2=A2*(n-i)*(n-i)+B2*(n-i)+C2;
        profit=Y1+Y2;
        maxProfit=max(profit,maxProfit);
    }
    printf("%d\n",maxProfit);

}
```
## ==人口遷移==
### <font color="0E81A6">題目</font>
[人口遷移](https://zerojudge.tw/ShowProblem?problemid=f313)
### <font color="0E81A6">核心</font>
模擬、二維陣列
### <font color="0E81A6">思路</font>
簡易模擬題。
```c++=
#include<bits/stdc++.h>
using namespace std;
#define N 55
int main()
{
    int R,C,k,m;
    int city[N][N],di[4]={1,0,-1,0},dy[4]={0,1,0,-1},people_num[N][N];
    scanf("%d%d%d%d",&R,&C,&k,&m);
    memset(city,-1,sizeof(city));
    for(int i=1;i<=R;i++)
    {
        for(int j=1;j<=C;j++) scanf("%d",&city[i][j]),people_num[i][j]=city[i][j]/k;
    }
    while(m--)
    {

        for(int i=1;i<=R;i++)
        {
            for(int j=1;j<=C;j++)
            {
                if(city[i][j]==-1) continue;
                for(int d=0;d<4;d++)
                {
                    if(city[i+di[d]][j+dy[d]]!=-1)
                    {
                        city[i+di[d]][j+dy[d]]+=people_num[i][j];
                        city[i][j]-=people_num[i][j];
                    }
                }
            }
        }
        for(int i=1;i<=R;i++)
        {
            for(int j=1;j<=C;j++) people_num[i][j]=city[i][j]/k;
        }
    }
    int max_n=0,min_n=INT_MAX;
    for(int i=1;i<=R;i++)
    {
        for(int j=1;j<=C;j++)
        {
            if(city[i][j]==-1) continue;
            max_n=max(city[i][j],max_n);
            min_n=min(city[i][j],min_n);
        }
    }
    printf("%d\n%d\n",min_n,max_n);

}
```
## ==勇者修練==
### <font color="0E81A6">題目</font>
[勇者修練](https://zerojudge.tw/ShowProblem?problemid=f314)
### <font color="0E81A6">核心</font>
dp、模擬
### <font color="0E81A6">思路</font>
一列一列考慮，任一點有可能從左或右或上過來，而頭尾只會從上下來。
```c++=
#include<bits/stdc++.h>
using namespace std;
#define N 10005
#define M 55
int A[N];
int dp[M][N]={0};
int m,n;
int main()
{
    scanf("%d%d",&m,&n);
    for(int i=1;i<=m;i++)
    {
        for(int j=1;j<=n;j++) scanf("%d",A+j);

        int l[N]={0},r[N]={0};
        for(int j=1;j<=n;j++)
        {
            if(j==1) l[j]=dp[i-1][j]+A[j];
            else l[j]=max(dp[i-1][j],l[j-1])+A[j];
        }
        for(int j=n;j>=1;j--)
        {
            if(j==n) r[j]=dp[i-1][j]+A[j];
            else r[j]=max(dp[i-1][j],r[j+1])+A[j];
        }
        for(int j=1;j<=n;j++)
        {
            dp[i][j]=max(l[j],r[j]);
        }
    }
    int sum=INT_MIN;
    for(int j=1; j<=n; j++)
    {
        sum=max(dp[m][j],sum);
    }
    printf("%d\n",sum);


}
```
## ==低地距離==
### <font color="0E81A6">題目</font>
[低地距離](https://zerojudge.tw/ShowProblem?problemid=f315)
### <font color="0E81A6">核心</font>
BIT
### <font color="0E81A6">思路</font>
[大佬思路](https://hackmd.io/@QWERTYPIG/Sy3rQgPb2#%E7%AC%AC%E5%9B%9B%E9%A1%8C-%E4%BD%8E%E5%9C%B0%E8%B7%9D%E9%9B%A2)
```c++=
#include<bits/stdc++.h>
using namespace std;
long long ans=0;
pair<int,int> arr[100010];
struct BIT
{
    int sz;
    vector<int> dat;
    void init(int n)
    {
        sz=n;
        dat.assign(n+1,0);
        return;
    }
    void upd(int id,int x)
    {
        for(int i=id;i<=sz;i+=i&-i) dat[i]+=x;
        return;
    }
    int sum(int id)
    {
        int ans=0;
        for(int i=id;i>0;i-=i&-i) ans+=dat[i];
        return ans;
    }
}bit;
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=2*n;i++)
    {
        int a;
        scanf("%d",&a);
        if(arr[a].first==0) arr[a].first=i;
        else arr[a].second=i;
    }
    bit.init(2*n);
    for(int i=1;i<=n;i++)
    {
        ans+=bit.sum(arr[i].second-1)-bit.sum(arr[i].first);
        bit.upd(arr[i].first,1);
        bit.upd(arr[i].second,1);
    }
    printf("%lld\n",ans);
}
```