timus 1658. Sum of Digits URAL 解題報告 DP 數字位數和……

timus  1658. Sum of Digits   URAL  解題報告   DP 數字位數和……

給每位上的數的和,和平方之後的和……  然後求出這個數的最小值,不能 的話輸出IMPOSSIBLE……
鬱悶了好久,這個題一直不會做,因爲既要照顧位數要少,還要照顧小數在前面,而且狀態轉移的話還不好想,因爲當時想到,一個數位數和增加,平方和增加的很巧妙,說不定是從把多餘的和平均到各個位數上,由於每個位上的基數不同,那麼增加相同的數發揮的作用也不相同;那麼好麻煩啊,後來看了別人的解題報告還一直懷疑有錯誤,非常鬱悶,還一直找bug,後來才明白,這種情況不會出現,我當初思考的是有木有這樣一種狀況,就是位數和還有平方和變大之後位數沒有改變,只不過把多餘的和轉移到不同的位上,比如說,和爲i,平方和爲j,變成i+num,j+num*num之後,位數沒有改變只不過把多餘的num分到不同的位上,
f[9][41] = f[3][5],而不是f[9][41]=f[9-6][41-36]+1   雖然我現在找到的代碼成功解決了這個問題,但是沒有想明白爲什麼解決了這個問題……
各位大神,有明白的解釋下,謝謝!
參考博客

下面的代碼再解釋下,先把最少的位數確定,然後每一位上的數字可以互換的,所以排序輸出既可以了……
#include<iostream>
#include<string>
#include<sstream>
#include<string.h>
#include<algorithm>
#include<cstdio>
#include<stdlib.h>
using namespace std;
#define INF 0x7ffffff


string str;
int dp[910][8110];
int dig[910][8110];
int ans[110],tot;
void init()
{
    for(int i=0;i<901;++i)
    {
        for(int j=0;j<8101;++j)
        {
            dp[i][j]=INF;
        }
    }dp[0][0]=0;
    for(int i=1;i<901;++i)
    {
        for(int j=i;j<8101;++j)
        {
            for(int k=1;k<10;++k)
            {
                int tmp;
                if(i>=k&&j>=k*k&&(tmp=dp[i-k][j-k*k]+1)<dp[i][j])
                {
                    dp[i][j]=tmp;
                    dig[i][j]=k;
                }
            }
        }
    }

}

void write(int s1,int s2,int cnt)
{
    if(cnt==0)return;
    ans[cnt]=dig[s1][s2];
    write(s1-ans[cnt],s2-ans[cnt]*ans[cnt],cnt-1);
}
int main()
{
    init();
    int t,s1,s2;
    cin>>t;
    while(t--)
    {
        scanf("%d %d",&s1,&s2);
       // if(dp[s1][s2]>100)puts("okokokokok");
        if(s1>900||s2>8100||dp[s1][s2]>100)
        {///主題題目中所給的位數是100位,所以各位和不可能超過900……
            printf("No solution\n");continue;
        }
        tot=dp[s1][s2];

        write(s1,s2,tot);
        sort(ans+1,ans+tot+1);///找出最短几位就可以滿足之後然後把數字排序即可
        for(int i=1;i<tot+1;++i)
        {
            printf("%d",ans[i]);
        }cout<<endl;
    }


}



發佈了76 篇原創文章 · 獲贊 9 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章