HDU 5355 Cake

HDU 5355 Cake


更新後的代碼:

今天重新做這道題的時候想了很多種思路

最後終於想出了自認爲完美的思路,結果卻超時

真的是感覺自己沒救了

最後加了記憶化搜索,AC了

好了先說下思路吧,不知道大家住沒注意m<=10

我們可以把大部分的數據寫成成對的形式例如n=27 m=6的這組數據

第1份  27  16

第2份  26  17

第3份  25  18

第4份  24  19

第5份  23  20

第6份  22  21

剩下1~15搜索出6等份分給所有人

這樣成對出現的數蛇形數我們去處儘量多的偶數條

保證剩下的數的個數大於等於2*m小於4*m個

所以剩下的小於4m(小於40)個數我們只解用搜索就好了

所以n 的範圍就變成1~40,m的範圍1~10這樣我們記錄這些的結果(防止這樣的數據大量重複出現)

這樣如果我們有數據15 6計算過後

n=27  m= 6

n=39  m=6

n=15+(任意被的12) m=6

我們都不需要搜索了

就這樣這個問題就解決了


#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#define maxn 100005
#define ll __int64
#define cnm c[nu][m]
using namespace std;
int v[15][maxn];
ll m,n;
//fun函數定義將1-num平均分給l-r個人
int a[15][50];
int si[15];
bool b[50];
int dp[50][10]={0};
int c[50][10][15][50]={0};
ll ave,nu;
bool dfs(int sum,int g,int s){
    if(sum==ave){g++;sum=0;s=1;}
    if(g==m-1){
        for(int i=1;i<=nu;i++)
            if(!b[i])a[g][++a[g][0]]=i;
        return true;
    }
    for(int i=s;i<=nu;i++){
        if(sum+i>ave) return false;
        if(!b[i]){
            b[i]=true;
            a[g][++a[g][0]]=i;
            if(dfs(sum+i,g,i+1)) return true;
            b[i]=false;
            a[g][0]--;
        }
    }
    return false;
}

bool fun(ll num){
    if(num>=4*m-1){
        for(int i=0,j=0;i<m;i++,j++){
            v[i][si[i]++]=num-j;
            v[i][si[i]++]=num-2*m+1+j;
        }
        return fun(num-2*m);
    }
    else {
        nu=num;
        ave=(num+1)*num/2/m;
        int b;
        if(dp[num][m]==0){
            if(dfs(0,0,1)){
                dp[num][m]=1;
                for(int i=0;i<m;i++)
                    for(int j=0;j<=a[i][0];j++)
                        cnm[i][j]=a[i][j];
            }
            else dp[num][m]=-1;
        }
        if(dp[nu][m]==1) return true;
        return false;
    }
}
void out(int n){
    printf("YES\n");
    for(int i=0;i<n;i++){
        printf("%d",si[i]+cnm[i][0]);
        for(int j=0;j<si[i];j++) printf(" %d",v[i][j]);
        for(int j=0;j<cnm[i][0];j++) printf(" %d",cnm[i][j+1]);
        printf("\n");
    }
}
void Init(){
    memset(si,0,sizeof(si));
    memset(a,0,sizeof(a));
    memset(b,0,sizeof(b));
}
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%I64d%I64d",&n,&m);
        ll su=n*(n+1)/2;
        ll av=su/m;
        if(su%m||av<n)printf("NO\n");
        else{
            Init();
            bool ok=fun(n);
            if(ok)out(m);
            else printf("NO\n");
        }
    }
    return 0;
}

 




/*

此代碼存在侷限性數據更新後已不能在AC

待更新……

*/

這個題目看上去的時候第一感覺就是暴力,結果真的一遍就過了


#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#define maxn 100005
#define ll __int64
using namespace std;
int a[maxn];
vector <int > v[maxn];
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        ll n,m;
        scanf("%I64d%I64d",&n,&m);
        ll sum =(n+1)*n/2;
        if(sum%m==0){
            ll ave=sum/m;
            if(ave<n)
                printf("NO\n");
            else{
                memset(v,0,sizeof(v));
                memset(a,0,sizeof(a));
                int t=ave,A=0;
                int flag=0;
                for(int i=n;!flag&&i>=1;i--){
                    if(a[i]==0){
                        t-=i;
                        v[A].push_back(i);
                        a[i]=1;
                    }
                    if(i-1>t){
                        for(int j=i-1;t&&j>=1;j--){
                            if(t>=j&&a[j]==0){
                                v[A].push_back(j);
                                t-=j;
                                a[j]=1;
                            }
                        }
                    }
                    if(t==0){
                        t=ave;
                        A++;
                    }
                }
                if(A==m){
                    printf("YES\n");
                    for(int i=0;i<m;i++){
                        printf("%d",v[i].size());
                        for(int j=0;j<v[i].size();j++)
                            printf(" %d",v[i][j]);
                        printf("\n");
                    }
                }
                else
                    printf("NO\n");
            }
        }
        else
            printf("NO\n");
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章