2018/12/11 zhoulian 6 - h
阿新 • • 發佈:2018-12-11
#include<stdio.h> #include<iostream> #include<algorithm> #include<string.h> using namespace std; int n; int pri[1200]; int m; // 第一種情況 int cnt=0; // 陣列下標 int sum=0; // 菜的總價 int k=0; // k= m-5 ; int mm; // 第二種情況 int mmm=99999; // 第三種情況 char vis[1200]; // 'Y'為取,'N'為不取 int GetRes(void){ int p=0; // 當前陣列下標 int temp=0; // 當前子集合 while(p >= 0){ if('N' == vis[p]){ //選中當前項 vis[p] = 'Y'; temp+=pri[p]; if(temp == k){ return1; } else if(temp > k){ vis[p] = 'N'; //重置 temp-=pri[p]; } p++; } if(p >= n){ while('Y' == vis[p-1]){ p--; vis[p]='N'; temp-=pri[p]; if(p < 1){ return 0; } } while('N' == vis[p-1]){ p--; if(p < 1){ return 0; } } vis[p-1] = 'N'; temp-=pri[p-1]; } } return 0; } int main() { while(1){ //輸入菜的數量 scanf("%d",&n); if(n==0){ break; } cnt=0; sum=0; mmm=99999; //初始化 memset(pri,0,sizeof(pri)); memset(vis,0,sizeof(vis)); for(int i = 0 ; i < n ; i++){ scanf("%d",&pri[i]); // 輸入每個菜的價格 vis[i]='N'; sum+=pri[i]; } scanf("%d",&m); // 輸入卡的餘額 mm=m; k=m-5; if(m<5){ //情況1 printf("%d\n",m); continue; } if(sum<m){ // 情況2 printf("%d\n",m-sum); continue; //輸出 結束本次迴圈 } sort(pri,pri+n); //從小到大排好 if(GetRes()){ // 情況3 (如果 pri[]中 能有數相加== k ,那麼就是5 - pri[]中最大的 // 得到的結果最小) mmm=5-pri[n-1]; } for(int i = n-2 ; i >= 0 ; i--){ // 從大到小 減 if(k-pri[i]>=0){ k-=pri[i]; } } m = k+5-pri[n-1]; for(int i = 0 ; i < n-1 ;i++){ // 從小到大 減 if(mm-pri[i]>=5){ mm-=pri[i]; } } mm=mm-pri[n-1]; m=min(mm,m); m=min(mmm,m); //取最小 printf("%d\n",m); } return 0; }
在一個數組中任意個數 之和 等於 給定的數 , 輸出陣列中這幾個數 ( 輸出的是一種情況)
#include <iostream> using namespace std; #include <stdio.h> int len; int sum; int data[100000]; // 資料. char output[100000]; // 所求子集元素,與輸入資料對應,'Y'為取.‘N’為不取 void GetInput(){ int i; cin >> len >> sum ; for(i = 0; i < len; i++){ scanf("%d", &data[i]); output[i] = 'N'; } } int GetRes(){ int p = 0; // 指向當前值. int temp = 0; // 當前子集合和. while(p >= 0){ if('N' == output[p]){ // 選中當前項. output[p] = 'Y'; temp += data[p]; if(temp == sum){ return 1; } else if(temp > sum){ output[p] = 'N'; temp -= data[p]; } p++; } if(p >= len){ while('Y' == output[p-1]){ p--; output[p] = 'N'; temp -= data[p]; if(p < 1){ return 0; } } while('N' == output[p-1]){ p--; if(p < 1){ return 0; } } output[p-1] = 'N'; temp -= data[p-1]; } } return 0; } void PrintRes(){ int i ; for(i = 0; i < len; i++) { if('Y' == output[i]) { // best[k]=data[i]; cout<<data[i]<<" "; // k++; } } cout<<endl; // for( i = 0 ; i < k-1 ; i ++ ) //cout << best[i] << " "; //cout<<best[i]<<endl; } int main() { GetInput(); if(GetRes()) { PrintRes(); } else { cout<<"No Solution!"<<endl; } return 0; }
(回溯法:遇到合適的就取,取到後面的時候滿足不了,就後退,重新取下一個滿足的):
輸入:陣列長度 定值
陣列中的數
例如:5 10
4 5 2 6 2
輸出 : 4 6