Fake Maxpooling、碗的叠放、着色方案

一、Fake Maxpooling

题目链接
输入n,m,k;
在n行m列的矩阵中找出每一个k*k的矩阵中最大的数相加。
A{i,j} = lcm(i, j):矩阵的元素为行和列的最小公倍数。
思路:滑动窗口。
代码:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <deque>
using namespace std;
const int maxn=5010;
int a[maxn][maxn],ans[maxn][maxn];
deque<int> win(maxn);
int lcm(int x,int y)
{
   return y?lcm(y,x%y):x;
}
void f(int n, int len, int *arr, int *ans)
{
    win.clear();
    for(int i=1; i<=n; i++)
    {
        while(!win.empty()&&arr[win.back()]<arr[i])
            win.pop_back();
        while(!win.empty()&&win.front()<i-len+1)
            win.pop_front();
        win.push_back(i);
        if(i+1>=len)
            ans[i-len+1]=arr[win.front()];
    }

}
int main()
{
    ios::sync_with_stdio(false);
    int n,m,k,i,j;
    cin>>n>>m>>k;
    if(n>m)
    {
        int t;
        t=n,n=m,m=t;
    }
    for(i=1; i<=n; i++)
        for(j=i; j<=m; j++)
        {
            int t=i*j/lcm(i,j);
            a[i][j]=a[j][i]=t;
        }
    for(int i=1; i<=n; i++)
        f(m,k,a[i],ans[i]);
    for(int i=1; i<=m; i++)
    {
        win.clear();
        for(int j=1; j<=n; j++)
        {
            while(!win.empty()&&ans[win.back()][i]<ans[j][i])
                win.pop_back();
            while(!win.empty()&&win.front()<j-k+1)
                win.pop_front();
            win.push_back(j);
            if(j+1>=k)
                ans[j-k+1][i]=ans[win.front()][i];
        }
    }
    long long result=0;
    for(int i=1; i<=n-k+1; i++)
        for(int j=1; j<=m-k+1; j++)
            result+=ans[i][j];
    cout<<result<<endl;
    return 0;
}

二、碗的叠放

题目链接
给出每个碗的高、下底半径、上口半径。求出这些碗叠在一起后的最小高度。
数据范围小,可以用枚举
解题思路参考
代码:

#include <iostream>
#include <algorithm>
using namespace std;

typedef long long ll;
const ll INF=0x3f3f3f3f;

struct Bowl
{
    double h,r1,r2,slope;
};
Bowl bowl[20];
double t[20];
int index[20];
double f(Bowl b1,Bowl b2)
{
    if(b1.r1>=b2.r2)
        return b2.h;
    if(b1.r2<=b2.r1)
        return 0;
    if(b1.slope<=b2.slope)
    {
        if(b1.r1<=b2.r1)
            return 0;
        else return (b1.r1-b2.r1)*b2.h/(b2.r2-b2.r1);
    }
    else{
        if(b1.r2>b2.r2)
            return max(0.0,b2.h-b1.h*(b2.r2-b1.r1)/(b1.r2-b1.r1));
        else return max(0.0,b2.h*(b1.r2-b2.r1)/(b2.r2-b2.r1)-b1.h);
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n,i,j;
    cin>>n;
    for(i=0; i<n; i++)
    {
        cin>>bowl[i].h>>bowl[i].r1>>bowl[i].r2;
        bowl[i].slope=(bowl[i].r2-bowl[i].r1)/bowl[i].h;
        index[i]=i;
    }
    double re=0,ans=INF;
    do
    {
        re=0;
        for(i=0; i<n; i++)
        {
            t[i]=0;
            for(j=0;j<i;j++)
                t[i]=max(t[i],t[j]+f(bowl[index[i]],bowl[index[j]]));
            re=max(t[i]+bowl[index[i]].h,re);
        }
        ans=min(ans,re);
    }
    while(next_permutation(index,index+n));
    cout<<(int)(ans+0.5)<<endl;
    return 0;
}

三、着色方案

题目描述
有k种油漆,每种油漆可以涂ci个木块, 所有油漆刚好足够涂满所有木块,即c1+c2+…+ck=n。任意两个相邻木块颜色不同的着色方案。
求方案数。
解题思路参考
代码:

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
const int mod=1000000007;
ll t[10];
ll dp[20][20][20][20][20][10];
ll dfs(int a,int b,int c,int d,int e,int w)
{
    if(dp[a][b][c][d][e][w]!=-1)
        return dp[a][b][c][d][e][w];
    if(a+b+c+d+e==0)
        return 1;
    ll ans=0;
    if(a)
        ans=(ans+(a-(w==2))*dfs(a-1,b,c,d,e,1))%mod;
    if(b)
        ans=(ans+(b-(w==3))*dfs(a+1,b-1,c,d,e,2))%mod;
    if(c)
        ans=(ans+(c-(w==4))*dfs(a,b+1,c-1,d,e,3))%mod;
    if(d)
        ans=(ans+(d-(w==5))*dfs(a,b,c+1,d-1,e,4))%mod;
    if(e)
        ans=(ans+e*dfs(a,b,c,d+1,e-1,5))%mod;
    return dp[a][b][c][d][e][w] = ans;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int k,i;
    cin>>k;
    memset(t,0,sizeof(t));
    memset(dp,-1,sizeof(dp));
    for(i=0; i<k; i++)
    {
        int d;
        cin>>d;
        t[d]++;
    }
    cout<<dfs(t[1],t[2],t[3],t[4],t[5],0)<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44350170/article/details/107417585