郵票面值設計(NOIP 1999)
阿新 • • 發佈:2018-12-06
很有意思一道題,深搜加遞推動態規劃:
【問題描述】
給定一個信封,最多隻允許貼N張郵票,計算在給定K(N+K<=40) 種郵票的情況下(所有的郵票數量都足夠),如何設計郵票的面值,能得到最大max ,使得1-max之間的每一個郵資值都能得到。
例如,N=3,K=2,如果面值分別為1分、4分,則在l分至6分之間的每一個郵資值都能得到(當然還有8分、9分和12分):如果面值分別為1分、3分,則在1分至7分之間的每一個郵資值都能得到。可以驗證當N=3,K=2時,7分就是可以得到連續的郵資最大值,所以MAX=7,面值分別為l分、3分。
【樣例輸入】
N=3 k=2
【樣例輸出】
1 3
MAX=7
#include"iostream" #include"cstdio" #include"algorithm" #include"vector" using namespace std; int f[2000000],a[51],b[51],res=0; int k,n; void find() { int t=0; f[0]=0; while(f[t]<=n) { t++; f[t]=9999; for(int i=0;i<k;i++) { if(t>=a[i]&&f[t-a[i]]+1<f[t]) f[t]=f[t-a[i]]+1; } } if(t-1>res) { res=t-1; for(int i=0;i<k;i++) { b[i]=a[i]; } } } void dfs(int cur) { if(cur==k) { find(); return; } for(int i=a[cur-1];i<a[cur-1]*n+2;i++) { a[cur]=i; dfs(cur+1); } } int main() { cin>>n>>k; a[0]=1; dfs(1); for(int i=0;i<k;i++) { cout<<b[i]<<' '; } cout<<endl<<"MAX="<<res<<endl; return 0; }