题意:给你一个数让你分解成几个含61的数
题解:首先判断是否本身是61数
如果不是:
6161以上的数可以直接分解为两个数
若一个数*******
(*******-6161)=&&&&&&&
那么解就是&&&&&61 和61&&
6161以下的数使用背包处理
首先判断是否为61数,如果是就是一个背包的物品
把所有物品做一个完全背包再记录状态转移
jd函数判断数x是否为61数
deal分解6161以下的数
t数组记录状态转移
f数组做一个完全背包
#include<iostream>
#include<cstdio>
using namespace std;
bool jd(int x){
int temp=x;
while(temp!=0){
if(temp%100==61)return true;
else temp/=10;
}
return false;
}
int f[10000],t[10000];
int queue[10000],node;
void deal(int x){
int queue[6600],l,r;
l=0;r=1;
queue[0]=x;
while(l!=r){
if(f[t[queue[l]]]==1)printf(" %d",t[queue[l]]);
else queue[r++]=t[queue[l]];
if(f[queue[l]-t[queue[l]]]==1)printf(" %d",queue[l]-t[queue[l]]);
else queue[r++]=queue[l]-t[queue[l]];
l++;
}
}
int main(){
int i,j,a,b,k,m,n,t1,num,temp,x,ans;
scanf("%d",&t1);
node=0;
for(i=1;i<=6161;i++)
if(jd(i)){f[i]=1;queue[++node]=i;}
for(i=1;i<=node;i++)
for(j=i;j<=6161;j++)
if(f[j])
if(queue[i]+j<6161)
if(f[queue[i]+j]==0||f[queue[i]]+f[j]<f[queue[i]+j]){
f[queue[i]+j]=f[queue[i]]+f[j];
t[queue[i]+j]=j;
}
for(k=1;k<=t1;k++){
scanf("%d",&num);if(jd(num))printf("1 %d\n",num);
else
if(num>=6161){
temp=num;
temp-=6161;
a=61;
b=6100;
b+=temp%100;
a+=temp/100*100;
printf("2 %d %d\n",a,b);
}
else{
temp=num;
printf("%d",f[temp]);
if(f[temp])deal(temp);
printf("\n");
}
}
}